0-basedで考える。また、(wi,vi,ci)があらかじめ色の昇順にソートされているとする。f(x,y,z)を、物 0,1,...,x−1からy色以下、重さz以下になるように選んで達成できる最大価値とすると、答えはf(N,C,W)である。
fの漸化式を考える。物xが色の先頭にない場合は普通のナップサック問題と同じように遷移する:
f(0,y,z)=0 f(x,y,z)=max{f(x−1,y,z)f(x−1,y,z−wx−1)+vx−1(物x−1を入れない)(物x−1を入れる)
物xxxがその色の先頭にある時はx−1x-1x−1から色が変わるため、新しい色を使う場合と使わない場合を比較しなければならない。p(x)p(x)p(x)を物xxxのひとつ前の色を持つ品物の先頭とすると、次のように書ける:
f(x,y,z)=max{f(x−1,y−1,z)(物x−1の色を使うがx−1は入れない)f(x−1,y−1,z−wx−1)+vx−1(物x−1の色を使い、x−1を入れる)f(p(x),y,z)(物p(x), ..., x−1の色を飛ばす)
f(x, y, z) = \max \begin{cases}
f(x-1, y-1, z) & (\text{物x−1x-1x−1の色を使うがx−1x-1x−1は入れない})\\
f(x-1, y-1, z-w_{x-1})+v_{x-1} & (\text{物x−1x-1x−1の色を使い、x−1x-1x−1を入れる}) \\
f(p(x), y, z) & (\text{物p(x)p(x)p(x), ..., x−1x-1x−1の色を飛ばす})
\end{cases}
f(x,y,z)=max⎩⎪⎨⎪⎧f(x−1,y−1,z)f(x−1,y−1,z−wx−1)+vx−1f(p(x),y,z)(物x−1の色を使うがx−1は入れない)(物x−1の色を使い、x−1を入れる)(物p(x), ..., x−1の色を飛ばす)
ただし、y=0y=0y=0のときはもう新しい色を使えないのでf(x,0,z)=f(p(x),0,z)f(x,0,z) = f(p(x), 0, z)f(x,0,z)=f(p(x),0,z)である。計算量はO(NWC){\mathcal O}(NWC)O(NWC)。
以前に見たときは何がなんだかわからなかったが、今見たらあっさり解けた。ソートしてナップサックは典型らしい。