数学递推

被机智的逼哥发现后,旋少很不甘心把自己的辛苦的血汗钱发出去,但是又不得不吐出来。于是他打算把这些钱发出去,但是不是简单的发红包。
为了活跃气氛,他决定这样发红包这:

首先,先发一个小红包(每人一分钱)假设所有人都先后随机的领取了
然后,他会把红包的领取时间排序
最后,如果领取时间排序的序号就是AC红包里面的排名,那么“恭喜你,你变成了旋少的有缘人”有缘人会平分得到旋少所有的“血汗钱”。

这活动虽然有趣但是,逼哥眉头一皱,发现事情并没有那么简单。

他觉得有必要计算一下没有人成为旋少有缘人的概率。
Input输入数据的第一行是一个整数T,表示测试实例的个数,然后是T 行数据,每行包含一个整数n(1<n<=20),表示参加的人数。

Output对于每个测试实例,请输出没有人成为旋少有缘人的概率,每个实例的输出占一行, 结果保留两位小数(四舍五入),具体格式请参照sample output。

Sample Input
1
2
Sample Output
50.00%

这个题为错排,有递推公式,但是好像可以打表然后找规律,但我不会暴力打表,还需努力!

#include<stdio.h>
#include<string.h>
double fun(int n)
{
    double mul=1;
    int i;
    for(i=1;i<=n;i++)
    {
        mul=mul*i;
    }
    return mul;
}//阶乘
int main()
{
    int t,i;
    int n;
    long long a[1000];
    scanf("%d",&t);
    a[1]=0;a[2]=1;
    while(t--)
    {
        scanf("%d",&n);
        if(n>=3)                                      //1个人和两个人没办法 用递推公式
        {
            for(i=3;i<=n;i++)
            {
            a[i]=(i-1)*(a[i-1]+a[i-2]);        //关键的递推公式,假设有n个人,n-1个人全部错排后,第n个人与前面n-1个人任意交                                                                 换,其结果均错排,有(n-1)*a[n-1];

                                                             n-2个人全部错排后,也就是说第n-1个人、第n个人拿的是正确的,那么只需第n个人与                                                              第n-1交换,有(n-1)*a[n-2];

                                                             所以 a[n]=(n-1)*a[n-1]+(n-1)*a[n-2]
            }
           printf("%.2lf%%\n",(a[i-1]/fun(n))*100);
        }
        else printf("%.2lf%%\n",(a[n]/fun(n))*100);//1个人、2个人时的情况。
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_42370259/article/details/80551465
今日推荐