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