P3182 [HAOI2016] 放棋子
思路
这道题本质上是一道裸的错排问题。
首先分析一下题目,保证任意两个障碍不在同一行或同一列,那实际上障碍的具体位置就没有任何作用,我们总是可以通过交换行的位置,使第 \(i\) 行的障碍在第 \(i\) 列。
那就转化成了求 \(1\sim n\) 的一个排列,使 \(a_i\ne i\)。
令 \(f(n)\) 表示总方案数,\(a_n=x\) 时,考虑分类讨论:
- \(a_x=n\) 时,显然转换成了剩下 \(n-2\) 个元素的错排。
- \(a_x\ne n\) 时,则对这 \(n-1\) 个元素有 \(f(n-1)\) 种方法。
又因 \(x\) 有 \(n-1\) 种可能,可以得到式子: \(f(n)=(n-1)(f(n-1)+f(n-2))\)。
然后 c++ 党写高精度就可以了。
代码
python大法好
n=int(input())
ans=[0,0,1]
for i in range(3,n+1):
ans.append((i-1)*(ans[i-1]+ans[i-2]))
print(ans[n])