なら巡回置換に分解して数える典型問題。また、程度なら各順列を頂点として0-1BFSで探索すればよい。
満点について。まず、2つのロボットが与えられたときに、「少なくともいっぽうのインデックスが等しい」という関係が同値関係になっていることに注目する。このため、個のインデックスはノーコストで自由に行き来できるまとまりに分割できる。
具体例を挙げて考える:
1
9 5
5 8 2 4 6 7 9 3 1
2 5
5 6
3 4
7 8
8 9
この入力をグラフで図示すると次のような感じになる:
各頂点は、コスト0で相互に行き来できるインデックスを1つにまとめたものである。また、辺はに含まれる場所からに含まれる場所にちょうど1つの数を移動させなければならないことを表す。たとえばは最初インデックスにあって、インデックスに移動させたいので、頂点から頂点に辺を張っている。
こうしてグラフにしてみると、の場合と考え方はあまり変わらないことに気づく。つまり、このグラフ上の長さの閉路は回のスワップで解消できるので、グラフをいくつかの(辺素な)閉路に分割する問題であることがわかる。また、必要なスワップの回数は閉路の総数のみによって決まることも変わらない。
さて、閉路の総数だが、下のグラフのように分割方法によって異なる場合がある。
このグラフでは、長さ2の閉路を3つ選ぶことも長さ3の閉路を2つ選ぶこともできる。したがって、スワップの回数を減らすために、できるだけ多くの閉路に分割する方法を考えなければならない。ここまで考察を進めるとbitDPの形が見えた:
辺の集合を使用済みで、いま作りかけている閉路(まだ閉じていない)の始点が、終点がである時の、今までに作った閉路の総数の最大値。
遷移がなので計算量はになる。オーダー的には微妙なところだが、大半の状態は無効だし、各がすべてということもありえないので大丈夫だろう。割と余裕で通った。(計算量の評価がtightじゃないかも) 辺数がだから隣接リストで持てばだった。