hdu 2048
http://acm.hdu.edu.cn/showproblem.php?pid=2048
欧拉公式(错排公式)
错排,把第n个元素放在一个位置,比如位置k,一共有n-1种方法。
放编号为k的元素,这时有两种情况:
1.把它放到位置n上,那么,对于剩下的n-2个元素,就有F(n-2)种方法。
2.不把它放到位置n,这时,对于剩下的n-1全错排有F(n-1)种方法.
所以
f(n)=(n-1) {f(n-1)+f(n-2)}
ac码
#include<stdio.h> long long f[22]; double num(int t) { long long s=1; int k; for(k=1;k<=t;k++) s*=k; //printf("%.2lf",(float)f[t]/s); return (double)f[t]/s; } int main() { int n,i,j,t; f[1]=0; f[2]=1; f[3]=2; for(j=4;j<=20;j++) f[j]=(j-1)*(f[j-1]+f[j-2]); scanf("%d",&n); for(i=1;i<=n;i++) { scanf("%d",&t); //printf("$%lf\n",num(t)); printf("%.2lf%%\n",num(t)*100); } return 0; }
hdu2049不容易系列之-考新郎
http://acm.hdu.edu.cn/showproblem.php?pid=2049
n个新郎m个找错,同样是错排不过多了从n个中选m有多少可能罢了
#include<stdio.h> long long f[22]; long long s(int n,int m) { int i,j=1; long long sum=1; for(i=n;i>=n-m+1;i--) { sum=sum*i/j; j++; } return sum; } int main() { int t,m,n,i; f[1]=0;f[2]=1; for(i=3;i<=20;i++) f[i]=(i-1)*(f[i-1]+f[i-2]); scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); printf("%lld\n",s(n,m)*f[m]); } return 0; }
补充:
递推时应注意
EP .hdu牛肉字符2047 f(n)=2*f(n-1)+2*f(n-2); 从后至前思想
hdu2046三色填涂 f[n]=f[n-1]+f[n-2] 从前之后思想
对于地推的题 我们在找关系式的时候一定要找那些不变的量,在涂色问题上我们是从前向后面找的,这里为什么不行呢?我们来思考一下
若果说n-1是o的话,那么我们的n有两种取法e或者f。可是当我们考虑n-1 不是o的情况的时候,n-1就有两种取法,而后面的n又有三种取法,两个都是非一种取法,就是不可以的