题目的意思很清楚了……戳我戳我题目在这
题目思路:
其实我还真没怎么看出来这个是递推(嘤嘤自己好菜哇)……不过很清楚的是我们需要求出每个人拿到的都不是自己的牌子的情况有几种,按照日常经验,如果前n个人已经做到了错排(也就是拿的都不是自己的牌子),当第n+1个人来的时候,他跟任意一个人交换后就能做到这n+1个人都实现错排,!!但是注意还有一种情况,就是前n个人并没有实现完全错排,有一个人拿的牌子是正确的,这时第n+1个人来了之后,他只要跟这个拿对了牌子的人交换也可以做到n+1个人错排,这时可以看作是n-2个人实现了错排;
所以综上,递推式就可以出来了:
f [ i ] = ( f [ i - 2 ] + f [ i - 1 ] ) * ( i - 1 ) ;
题目代码:
#include<iostream>
#include<cstdio>
#include<math.h>
#define maxn 25
using namespace std;
long long f[maxn];
long long jc(int x)//计算阶乘
{
long long sum=1;
for(int i=1;i<=x;i++)
{
sum*=i;
}
//printf("%d: %lld\n",x,sum);
return sum;
}
int main(void)
{
int c,n;
scanf("%d",&c);
f[1]=0;
f[2]=1;
for(int i=3;i<=20;i++)
{
f[i]=(f[i-2]+f[i-1])*(i-1);
//printf("f[%d]: %lld\n",i,f[i]);
}
while(c--)
{
scanf("%d",&n);
long long x=jc(n);
double res=(double)f[n]/x;
//cout<<"res: "<<res<<endl;
res=round(res*10000)/10000;
//cout<<"res: "<<res<<endl;
//printf("f[n]: %d\n",f[n]);
printf("%.2f%%\n",res*100);
}
return 0;
}
呼呼