解法
基本的な考え方は普段のナップサックと同じで、ある重さになるような荷物の選び方の中での価値の最大値、を求めていきます。
今回、荷物には色が塗られており、種類以下でナップサックに荷物をつめなければなりません。
ということで、次のようなDPを考えます。
色を
種類使用して、重さの合計が
になるような荷物の選び方の中での価値の総和の最大値
ここで、が何を表しているかというと、
は次に見る荷物
の色
を
までの荷物を調べた段階で使用しているかどうか、そして
は
の荷物をすでに使用したかどうか、です。
が存在することで、全ての荷物を色の番号順でソートしておけば、同じ色を違う種類と判定することなく調べることができ、
が存在することで、荷物
を2つ以上いれる心配がなくなります。
ということで、あらかじめ全ての荷物を、色の番号が若い順にソートしておきます。
さて、荷物に注目ときのDPの遷移を考えていきます。
まず、DPテーブルの整理から始めます。というのも、番目の荷物を調べる時も、
番目の荷物を調べる時も、同じDPテーブルを再利用するためです。
2つのパターンが存在します。荷物の色
が、それ以前に登場しているかどうか、です。あらかじめソートをしているので、1つ前の荷物の色と比較して、違ったならば色
は
番目で初出、等しければそれ以前ですでに使用していることになります。
が
番目で初出ではない場合
番目の荷物について調べた際の、
、すなわち
番目の荷物を使用しているかどうか、という情報はもう必要ないので、
にまとめ上げます。ということで、
という処理と、
という操作をしてあげます。が
番目で初出だった場合
上の操作に加えて、のリセットも必要になります。
番目までの荷物の組み合わせで、色
の荷物を使用することがないからです。
です。それ以外は0で初期化するので、
という処理をしてあげます。
さて、DPテーブルの整理が終わったので、番目の荷物について考えていきます。
番目の荷物を使用しておらず、かつ
それまでで色
の荷物を使用していなければ、色の種類数に+1
色
の荷物を使用していれば、色の種類数はそのまま
となるので、DPの遷移は次のようになります。を使用した時点で、
はどちらも1になることに注意します。
ということで、この更新を行いつつ、の更新を行うごとに、全体での最大値を更新していけば、この遷移が終えた段階で、更新した最大値が答えとなります。