CODE THANKS FESTIVAL 2018-G:Sum of cards
詰め切るのが大変。本番で通した人たちすごい。
解法
カードについて,どちらか一方のスコアを獲得できるという状況だ。こういう状況は,グラフにしてみたくなる。からの数字が頂点,辺をの間に結んだグラフを考えよう。このグラフは,どの頂点も次数がであり,円形のグラフの集まりになる。のどちらを表にするかということを辺の向きで表現しよう。のうち,辺が入る方を表にする,ということにする。するとこの問題は以下のように書ける。
- 頂点の,円形のグラフが集まったグラフがある。各頂点にはからの数字が書いてある。このグラフの各辺に向きをつけ,各辺について,その辺が入る頂点に書いてある数字だけスコアを得る。少なくとも1本は辺が入ってくる頂点が個以上あるという条件のもとで,スコアの最大値を求めよ。
この問題を解いていこう。
円形のグラフが1つのとき
まずは円形のグラフが1つのときを考えよう。これをどう解くかで既に難しく思えるが,なんとここでdpをする(初見厳しくないか...)。どのような状態を持つべきかを考えよう。まず,便宜的に頂点番号をとする。は円形を構成する頂点の数とする。今どの頂点をみているかということは当然必要だろう。また,辺が入ってくる頂点の数に制約があるので,これも状態としてもっておきたい。さらに,この「辺が入ってくる頂点の数」をカウントするために重要な情報がある。それは,頂点頂点の間の辺の向きである。この頂点の向き次第で,頂点から頂点に移るときに,辺が入ってくる頂点の数が変わってくる。では
- :頂点までで辺が入る頂点の数が個,は頂点と頂点間の辺の向きを表す。のときに頂点から頂点に辺が入る。のときはその逆とする。
で十分だろうか?とりあえずこの場合の状態遷移について考えてみよう。便宜上,から始め,まで見た後,をみることにする。
のとき
でのときは以下の図のようになる。には辺が入っていなかったが,から出る辺で入ってくるようになるので,の添え字が1増える。
また,でのときは以下の図のようになる。にもともと辺が入っていたので,の添え字は増えない。
のとき
同様に考えればよい。
で
で
というわけで遷移が書けた。めでたしめでたし...と言いたいのだが,ここには罠がある。そう,いま考えているグラフは円形であったから,頂点と頂点の間から順に見ていって,最後に頂点と頂点の間を見ることになるが,このときに,上で述べた遷移にはならないパターンがある。以下の2つの図を見比べてみよう。
頂点から頂点に辺が出ているとき
頂点から頂点に辺が出ているとき
からに辺を伸ばすときは基本的に辺が入る頂点の数は増えるはずであったが,一周して戻ってくるときだけは,そうならないのである。よって,この3次元DPを素直にやるだけではうまくいかないのだ。ではどうするか?答えはシンプルで,「からに辺が出ているか」それとも「からに辺が出ているか」ということを状態としてもてばよい。そうすればからの遷移の際にのみ気をつけることで,この問題を回避できる。つまり
- :頂点までで辺が入る頂点の数が個,は頂点と頂点間の辺の向きを表す。のときに頂点から頂点に辺が入る。のときはその逆とする。は頂点と頂点の間の辺の向きを表す。のときに頂点から頂点に辺が入る。のときはその逆とする。
これで円形1つのときの問題を解くことができた。頂点が1つのみのときに注意。
円形のグラフが複数あるとき
さて,この問題でグラフを作ったときに,個の頂点すべてが連結になるとは限らない。よって,上のようにして各円について問題を解くことはできるが,その結果をまとめてやる必要がある。しかしこれは難しくない。円が全部で個あるとしよう。各円について,辺が入る頂点が個あるときのスコアの最大値がわかっている。このとき,であることに注意しよう。それならば
- :個目の円の番目のありえる辺が入る頂点の個数まで考えたときに,合計で辺の入る頂点の個数がのときのスコアの最大値
「番目のありえる辺が入る頂点の個数」というのは,とすると,に新たにという番号を振りなおしたと考えればよい。遷移はナップサック問題のような形になる。このうち,がより大きいものの最大値が答えとなる。
この解法全体の計算量はである。
実装
Submission #4129625 - CODE THANKS FESTIVAL 2018
これが参考になるかわからないが,上で述べたことを書くとこんな感じになる。各円の結果をまとめる部分で,前の円の大きさを保存しておかないといけなかったりなど,実装上面倒なことは多い。もう少し楽な実装方針があるかもしれない。
大変だが,勉強になる問題であった。ちなみにうまくやると最大費用流になるらしい。