链接:https://ac.nowcoder.com/acm/contest/5389/C
来源:牛客网
题目描述
牛牛即将要参加考试,他学会了填答题卡。
可惜他竖着的答题卡填成了横着的 :
好奇的他想知道对于 n 道题,每道题 n 个选项的答题卡 ( n * n 的矩阵 ),满足横答题卡和竖答题卡图形一致的方案数有多少种。
注:每道题只能选择一个选项,即 n * n 的矩阵中只能涂黑 n 个空。求横竖对称的方案数。
输入描述:
第一行给出 n。
输出描述:
输出方案数,答案对 1000000007 取模
示例1
输入
3
输出
4
说明
备注:
对于 50 %50\;\%50% 的数据有 n≤10n \leq 10n≤10
对于 100 %100\;\%100% 的数据有 n≤105n\le 10^5n≤105
这道题我也是经过大佬指点才做出来的。
他是这么说的:
第一行一定要填一个位置。所以枚举第一行填的位置。
设f(x , k)为x*x的网格,第一行填涂第k位的方案数。那么答案就为f(x) = f(x,1) + ... + f(x , x).
若k = 1.那么第一行第一列都不能填了,问题化简成f(x - 1).
k != 1 时,根据对称的要求,位置 (1 , k) 与 (k , 1) 都被填了.那么行和列都会少两个项。剩下来x - 2 行 x - 2 列。所以问题化简成f(x - 2) .. 推荐画画图就出来了.
所以递推式为: f(x) = f(x - 1) + (x - 1) * f(x - 2).
根据这个递推式,我就做出了这题。
下面是代码:
#include<bits/stdc++.h>
using namespace std;
long long f[1000001];
int main() {
int n;
scanf("%d",&n);
f[1]=1;
f[2]=2;
for(long long i=3;i<=n;i++)
f[i]=(f[i-1]%1000000007+(i-1)*f[i-2]%1000000007)%1000000007;
printf("%lld",f[n]);
return 0;
}