hdu1465不容易系列之一

来源:互联网 发布:乳液推荐 知乎 编辑:程序博客网 时间:2024/05/18 17:26

不容易系列之一

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19531    Accepted Submission(s): 8277


Problem Description
大家常常感慨,要做好一件事情真的不容易,确实,失败比成功容易多了!
做好“一件”事情尚且不易,若想永远成功而总从不失败,那更是难上加难了,就像花钱总是比挣钱容易的道理一样。
话虽这样说,我还是要告诉大家,要想失败到一定程度也是不容易的。比如,我高中的时候,就有一个神奇的女生,在英语考试的时候,竟然把40个单项选择题全部做错了!大家都学过概率论,应该知道出现这种情况的概率,所以至今我都觉得这是一件神奇的事情。如果套用一句经典的评语,我们可以这样总结:一个人做错一道选择题并不难,难的是全部做错,一个不对。

不幸的是,这种小概率事件又发生了,而且就在我们身边:
事情是这样的——HDU有个网名叫做8006的男性同学,结交网友无数,最近该同学玩起了浪漫,同时给n个网友每人写了一封信,这都没什么,要命的是,他竟然把所有的信都装错了信封!注意了,是全部装错哟!

现在的问题是:请大家帮可怜的8006同学计算一下,一共有多少种可能的错误方式呢?
 

Input
输入数据包含多个多个测试实例,每个测试实例占用一行,每行包含一个正整数n(1<n<=20),n表示8006的网友的人数。
 

Output
对于每行输入请输出可能的错误方式的数量,每个实例的输出占用一行。
 

Sample Input
23
 

Sample Output
12

今天做了一道有趣的排列组合题,代码很水,但个人觉得不是很好想(可能因为我比较菜QAQ
上网查了查题解,才知道这东西叫错排公式,于是学习了下= =
这题就是个错排公式的裸题,表示有n个物体放在n个位置上,要使得每个物品都放在不同的位置上,有多少种排法。我可以给大家分享下我的想法:
假设有n个物体,需要求出F(n),则可由前面的F(n-1)及F(n-2)推出。可以这么想,
(1)   前面n-1个位置已经满足条件每个物品都放在不同的位置上,这也就是F(n-1),然后将最后一个加进来的第n个,与前面任意一个换位置即可。所以这样的个数就是F(n-1)*(n-1);
(2)  OK,这样的情况已经搞定了,我们来继续考虑我们所忽视掉的,我们忽视掉了一类就是前面n-1个有n-2个满足条件,有一个在正确的位置上(我们假设这是第K个),这也就是F(n-2),然后将新加入的第n个,与这个K交换位置,即满足了条件每个物品都放在不同的位置上,然后这个K有n-1种(即前面n-1都有可能成为K),所以这种有F(n-2)*(n-1);
综合得到:F(n)=F(n-1)*(n-1)+F(n-2)*(n-1)   =》  F(n)=(n-1)*(F(n-1)+F(n-2))这就是错排公式的原型啦!!!!
最后给出AC代码:
#include<cstdio>#include<cstdlib>#include<iostream>#include<stack>#include<queue>#include<algorithm>#include<string>#include<cstring>#include<cmath>#include<vector>#include<map>#include<set>#define eps 1e-8#define zero(x) (((x>0?(x):-(x))-eps)#define mem(a,b) memset(a,b,sizeof(a))#define memmax(a) memset(a,0x3f,sizeof(a))#define pfn printf("\n")#define ll __int64#define ull unsigned long long#define sf(a) scanf("%d",&a)#define sf64(a) scanf("%I64d",&a)#define sf264(a,b) scanf("%I64d%I64d",&a,&b)#define sf364(a,b,c) scanf("%I64d%I64d%I64d",&a,&b,&c)#define sf2(a,b) scanf("%d%d",&a,&b)#define sf3(a,b,c) scanf("%d%d%d",&a,&b,&c)#define sf4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)#define sff(a) scanf("%f",&a)#define sfs(a) scanf("%s",a)#define sfs2(a,b) scanf("%s%s",a,b)#define sfs3(a,b,c) scanf("%s%s%s",a,b,c)#define sfd(a) scanf("%lf",&a)#define sfd2(a,b) scanf("%lf%lf",&a,&b)#define sfd3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)#define sfd4(a,b,c,d) scanf("%lf%lf%lf%lf",&a,&b,&c,&d)#define sfc(a) scanf("%c",&a)#define ull unsigned long long#define debug printf("***\n")const double PI = acos(-1.0);const double e = exp(1.0);const int INF = 0x7fffffff;;template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }template<class T> T lcm(T a, T b) { return a / gcd(a, b) * b; }template<class T> inline T Min(T a, T b) { return a < b ? a : b; }template<class T> inline T Max(T a, T b) { return a > b ? a : b; }bool cmpbig(int a, int b){ return a>b; }bool cmpsmall(int a, int b){ return a<b; }using namespace std;int main(){   // freopen("data.in","r",stdin);    int n;    ll dp[30];    mem(dp,0);    dp[1]=0,dp[2]=1;    for(int i=3;i<=20;i++)        dp[i]=(i-1)*(dp[i-1]+dp[i-2]);    while(~sf(n))    {        printf("%I64d\n",dp[n]);        //debug;    }    return 0;}

0 0