数学 ( 错排问题 )——HUD 2048

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

  • 分析:
    这是一道错排问题,属于组合数学中的问题之一。

    若一个排列中所有的元素都不再自己原来的位置上,那么这样的排列就称为原排列的一个错排。n个元素的错排数记为D(n)。

    错排公式:

    1. 把第n个元素放在一个位置,比如位置k,一共有n-1种方法;

    2. 放编号为k的元素,这时有两种情况:
      ⑴把它放到位置n,那么,对于剩下的n-1个元素,由于第k个元素放到了位置n,剩下n-2个元素就有D(n-2)种方法;
      ⑵第k个元素不把它放到位置n,这时,对于这n-1个元素,有D(n-1)种方法;

    3. 综上得到:D(n) = (n-1) [D(n-2) + D(n-1)],特殊地,D(1) = 0, D(2) = 1.
      D(n) = n! [(-1)^2/2! + … + (-1)^(n-1)/(n-1)! + (-1)^n/n!].

    4. 概率公式为: N(n) = (-1)^2/2! + … + (-1)^(n-1) / (n-1)! + (-1)^n/n!

    用容斥原理推导错排公式:

    正整数1, 2, 3, ……, n的全排列有 n! 种,其中第k位是k的排列有 (n-1)! 种;当k分别取1, 2, 3, ……, n时,共有n*(n-1)!种排列是至少放对了一个的,由于所求的是错排的种数,所以应当减去这些排列;但是此时把同时有两个数不错排的排列多排除了一次,应补上;在补上时,把同时有三个数不错排的排列多补上了一次,应排除;……;继续这一过程,得到错排的排列种数为
    D(n) = n! - n!/1! + n!/2! - n!/3! + … + (-1)^n*n!/n! = ∑(k=2~n) (-1)^k * n! / k!,
    即D(n) = n! [1/0! - 1/1! + 1/2! - 1/3! + 1/4! + … + (-1)^n/n!].
    其中,∑表示连加符号,k=2~n是连加的范围;0! = 1,可以和1!相消。

  • AC代码:

#include <iostream>

using namespace std;
int C;
int n;

__int64 f[25];

void init()
{
    f[1] = f[0] = 0;
    f[2] = 1;
     for(int i=3;i<25;i++)
    {
        f[i]=(i-1)*f[i-1]+(i-1)*f[i-2];
    }
}

int main()
{
    scanf("%d", &C);
    init();
    while(C--)
    {
        scanf("%d", &n);
        __int64 sum=1;
        for(int i=1;i<=n;i++)
            sum*=i;
        double ans = (double) f[n]*100/sum;

        printf("%.2lf%%\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值