考え方
最大で$2N = 16$人.ペアの組み方は\begin{aligned}
15!!
&= 15\times 13 \times \cdots \times 3 \times 1 \\
&=2,027,025
\end{aligned}
となる(例えば以下のコード).よって,全探索できる.
15!!
&= 15\times 13 \times \cdots \times 3 \times 1 \\
&=2,027,025
\end{aligned}
ans = 1 x = 15 while x > 0: ans *= x x -= 2 print(ans)
あとは,どうやってすべての場合を重複なく「列挙するか」,という問題になる.これは,どうやってすべての場合を重複なく「表現するか」がわかればよい.
ペアの組み方を
\begin{aligned}
P = [(1,2), (3,4), ..., (2N-1, 2N) ]
\end{aligned}
のように,ペアを要素としたリストで表すことを考える.P = [(1,2), (3,4), ..., (2N-1, 2N) ]
\end{aligned}
重複なく表記するためには,まず,各ペア$(x, y)$の順序を決めなくてはならない.そこで,常に$x < y$となるように表すことにする.
まだ,$P$内の並び順に不定性が残っている.そこで,$P = [(x_{1}, y_{1}), (x_{2}, y_{2}), ..., (x_{N}, y_{N})]$を$x_{1} < x_{2} < \cdots < x_{N}$となるように,第一要素でソートして表現することにする.
以上で,重複なく$P$を表すことができるようになった.
あとは,$P$の第一要素から順に生成する方法を考えれば良い.つまり,
- まだ選んでいない要素の中で最小の要素$x$を選び,
- $x$以外の要素$y$を選び,
- $(x, y)$を$P$に追加する
回答例
XORの単位元は$0$.N = int(input()) A = [list(map(int, input().split())) for _ in range(2 * N - 1)] ans = 0 def f(cur, score): global ans if not cur: ans = max(ans, score) return x = cur[0] for i in range(1, len(cur)): y = cur[i] nxt = cur[1:i] + cur[i + 1:] f(nxt, score ^ A[x - 1][y - 1 - x]) return f([i + 1 for i in range(2 * N)], 0) print(ans)