本题就是利用一个错排公式,一个数学组合就能解决
错排公式: f[1]=0;
f[2]=1;
f[3]=2;
f[4]=9;
f[n]=(n-1)*(f[n-1]+f[n-2]);
通用公式f[n]=n!*(1/2!-1/3!+1/4!-........+(-1)^n/n!
此题有个比较巧妙的地方,我看了别人代码才发现
就是求C(n,k)时 不能用n!/(k!*(n-k)!) 因为n!可能超long long
要用n*(n-1)*(n-2)*......(n-k+1) / k!
下面是代码:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int ans(int n,int k)
{
long long a1=1,a2=1;
for(int i=n; i>=n-k+1; i--)
a1*=i;
for(int j=1; j<=k; j++)
a2*=j;
return a1/a2;
}
int main()
{
long long i,j,k;
long long f[30];
f[0]=1;
f[1]=0;
f[2]=1;
f[3]=2;
for(i=4; i<30; i++)
{
f[i]=(i-1)*(f[i-1]+f[i-2]);
}
long long n;
while(cin>>n)
{
if(n==0)
break;
int k1;
long long sum=0;
if(n==1)
cout<<1<<endl;
else
{
for(k1=1; k1<=n/2; k1++)
{
sum+=ans(n,k1)*f[k1];
}
cout<<sum+1<<endl;
}
}
return 0;
}