HDU 2048(错排公式)

127 篇文章 0 订阅
85 篇文章 2 订阅

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2048

问题分析

n n 个人全没有中奖的概率 -> 发生这种情况的所有可能性/情况总数
我们来想一想全部错排该怎么求。
假设前n1个人都完成了错排,那么第 n n 个人可以和这n1个人任意一个互换,那么就完成了全部错排,此时方法数为 (n1)f(n1) ( n − 1 ) f ( n − 1 )
假设前 n1 n − 1 一个人未完成错排,但是前 n2 n − 2 个人已经完成了全部错排,第 n1 n − 1 个人还是自己的位置,所以只要第 n n 个人和第n1个人完成互换即可完成 n n 个人错排。但是,n1个人中那个未完成错排的人可能是这 n1 n − 1 个人里的任意一个,所以方法数为 (n1)f(n2) ( n − 1 ) f ( n − 2 )
所以错排总的方法数为

f(n)=(n1)(f(n1)+f(n2)) f ( n ) = ( n − 1 ) ( f ( n − 1 ) + f ( n − 2 ) )

最后所有情况的可能数为 n! n !

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
using namespace std;
const int N = 7E5;

int main()
{
    double a[21]={0,0,1};
    for(int i = 3; i < 21; ++i){
        a[i] = (i-1)*(a[i-1]+a[i-2]);
    }
    int t;
    cin>>t;
    while(t--)
    {
        long long sum = 1,n;
        cin>>n;
        for(int i = 1; i <= n; ++i)
            sum *=  i;
        printf("%.2f%%\n",a[n]*100/sum);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值