答题卡(C++)

链接:https://ac.nowcoder.com/acm/contest/5389/C

来源:牛客网

题目描述

牛牛即将要参加考试,他学会了填答题卡。

可惜他竖着的答题卡填成了横着的 :

好奇的他想知道对于 n 道题,每道题 n 个选项的答题卡 ( n * n 的矩阵 ),满足横答题卡和竖答题卡图形一致的方案数有多少种。

注:每道题只能选择一个选项,即 n * n 的矩阵中只能涂黑 n 个空。求横竖对称的方案数。

img

输入描述:

第一行给出 n。

输出描述:

输出方案数,答案对 1000000007 取模

示例1

输入

3

输出

4

说明

img

备注:

对于 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;
}
原创文章 75 获赞 126 访问量 1万+

猜你喜欢

转载自blog.csdn.net/liuzich/article/details/105886124