题目名称:大搬家
题目链接:http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?cid=584&pid=1001
思路:因为第三次搬家后的结果和第一次的结果完全相同,所以第二次和没搬家的时候也是完全相同的,那么很容易想到,这个搬家的方案是两家之间互搬或者有些人没动。
那么,假设有n户人需要搬家,符合条件的方案数为a[n],那么当又有一家人需要搬家的时候,如果他不搬,那么方案数为a[n],如果他要搬家,那么他可能与其中一户人家形成一对,则剩下的人的方案数为a[n-1]。则,a[n+1]=a[n]+n*a[n-1]。值得注意的是,n*a[n-1]会溢出int,所以要用long long来存。而且a[1]=1,a[2]=2。
代码如下
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<map>
#include<set>
#include<vector>
#include<iostream>
using namespace std;
#define RE(x) freopen(x,"r",stdin);
#define WR(x) freopen(x,"w",stdout);
const int N = 1000005;
const long long MOD = 1000000007;
const int MAXN = 1e7+9;
long long a[N]={0,1,2};
int main()
{
for(int i=3;i<N;i++)
{
a[i]=(a[i-1]+(i-1)*a[i-2])%MOD;
}
int t,n;
scanf("%d",&t);
for(int cc=1;cc<=t;cc++)
{
scanf("%d",&n);
printf("Case #%d:\n%lld\n",cc,a[n]);
}
return 0;
}