が小さいので、 集合に含まれる宝箱を全部開けられるような鍵の選び方をした時の最小コスト、を目指したくなる。(不可能な場合は。)
のDP
鍵で開けられる宝箱の集合をとするとき、と初期化して
をすべての鍵と集合について更新して求まるなら話は早い……が、これは集合の包含関係について全部処理しているわけではない。つまり、この方法で最終的に求まるのは 集合に含まれる宝箱を全部開けられて、に含まれない宝箱を一つも開けられないような鍵の選び方をした時の最小コスト、である。しかし、もう少し考えると、求めるのは全体集合に対する最小コストだったので、それでも問題ないことがわかる。1
コンテスト中はこの辺の理解にぱっと至らなくて、しばらく逡巡してしまった。
のDP
最初に目指したを直接求める方法を考えてみる。をすべてに初期化して、
とする。(重複する場合は小さい方を選ぶ。つまり、正確には。)を上位集合に関してゼータ変換すると、 宝箱の集合を一つの鍵で開ける場合の最小コスト、になっている。あとは、
を使って順次最小値を確定していけばよい。部分集合の効率的な列挙のやり方は https://topcoder.g.hatena.ne.jp/jackpersel/20100804/1281196966 に書いてある。
何個か宝箱の集合クエリを受け取ってそれに対する最小コストを返す問題の場合は、最後にをゼータ変換すればよい。 ↩︎