1. 程式人生 > >hdu1465不容易系列之一

hdu1465不容易系列之一

不容易系列之一

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 2 3
Sample Output
1
2
今天做了一道有趣的排列組合題,程式碼很水,但個人覺得不是很好想(可能因為我比較菜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;
}