【转】HDU-2048-神、上帝以及老天爷:错排

 

错排简化公式:

D(n) = [n!/e+0.5]其中e是自然对数的底,[x]为x的整数部分

#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstdio>
using namespace std;
const double e=exp(1);// e的1次方
int main()
{
    double arr[21], tmp=1.0;
    int t, n, i;
    for(int i=2; i<21; i++)
    {
            tmp*=i;
            arr[i]=round(tmp/e)/tmp;// round函数返回四舍五入整数值
    }

    scanf("%d", &t);
    while(t--)
    {
        scanf("%d", &n);
        printf("%.2f%%\n", arr[n]*100.0);
    }
	return 0;
}

N张字条的所有可能排列自然是N!(分母)。
现在的问题就是求N张字条的错排数f(N)(分子)。
首先我们考虑,如果前面N-1个人拿的都不是自己的票,即前N-1个人满足错排,现在又来了一个人,他手里拿的是自己的票。只要他把自己的票与其他N-1个人中的任意一个交换,就可以满足N个人的错排。这时有(N-1)*f(N-1)种方法。

#include<iostream>
#include<string>
#include<iomanip>
using namespace std;

int main()
{
    double arr[21]={0, 0, 1};

    for(int i=3; i<21; i++){
        arr[i]=(arr[i-1]+arr[i-2])*(i-1);
    }

    int t;
    cin>>t;
    while(t--)
    {
            int n;
            cin>>n;
            double tmp=1;
            for(int i=2; i<=n; i++)
                tmp*=i;

            cout<<fixed<<setprecision(2)<<(arr[n]/tmp)*100.0<<"%"<<endl;
    }
	return 0;
}

  

posted @ 2015-08-20 10:01  _SunDaSheng  阅读(246)  评论(0编辑  收藏  举报