zoukankan      html  css  js  c++  java
  • 23-新娘匹配(错排问题)

    /*   错排问题:
    问题: 十本不同的书放在书架上。现重新摆放,使每本书都不在原来放的位置。有几种摆法?
    这个问题推广一下,就是错排问题,是组合数学中的问题之一。考虑一个有n个元素的排列,若一个排列中所有的元素都不在自己原来的位置上,那么这样的排列就称为原排列的一个错排。 n个元素的错排数记为D(n)。 研究一个排列错排个数的问题,叫做错排问题或称为更列问题。
    错排问题最早被尼古拉·伯努利和欧拉研究,因此历史上也称为伯努利-欧拉的装错信封的问题。这个问题有许多具体的版本,如在写信时将n封信装到n个不同的信封里,有多少种全部装错信封的情况?又比如四人各写一张贺年卡互相赠送,有多少种赠送方法?自己写的贺年卡不能送给自己,所以也是典型的错排问题。
    以信封问题为例:

    1、当N=1和2时,易得解~,假设F(N-1)和F(N-2)已经得到,重点分析下面的情况:
    2、当有N封信的时候,前面N-1封信只可以有N-1或者 N-2封错装,因为后面只剩一个可以与前面的换。
    3、前者,对于每种错装,可从N-1封信中任意取一封和第N封错装,故=F(N-1)*(N-1)
    4、后者简单,只能是没装错的那封和第N封交换信封,没装错的那封可以是前面N-1封中的任意一个,故=F(N-2) * (N-1)。

    递归式:d[n]= (n-1)*( d[n-1]+ d[n-2]), 特殊地,D(1) = 0, D(2) = 1;

    上面是对于完全错排的分析,其实对于部分错排就简单了,例如n个数m个排,其实就是将m个错排,再从n中选m个出来,即确定是哪些错拍,就可以了。

    即w(n, m) = f(m) * C(n, m); c(n,m)表示从n个中选m个种类
    */

    #include <iostream>
    using namespace std;
    
    int cc(int n, int m){
        if(m == 1)
            return n;
        if(m == n)
            return 1;
        if(m == 0)
            return 1;
        return cc(n - 1, m) + cc(n - 1, m - 1);
    }
    
    long long fun(int m){  //就只是将int改为long long 就过了, 所以还是用longlong吧. http://acm.hdu.edu.cn/showproblem.PHP?pid=2049
        if(m == 0)
            return 0;
        if(m == 1)
            return 0;
        if(m == 2)
            return 1;
        return (m - 1) * (fun(m - 1) + fun(m - 2));
    }
    
    int main(){
        int c, m, n;
        
        cin >> c;
        while(c--){
            cin >> n >> m;
            cout << cc(n, m) * fun(m) << endl;
        }
        return 0;
    } 
    



  • 相关阅读:
    苹果一体机发射Wi-Fi
    iphone 屏蔽系统自动更新,消除设置上的小红点
    data parameter is nil 异常处理
    copy与mutableCopy的区别总结
    java axis2 webservice
    mysql 远程 ip访问
    mysql 存储过程小问题
    mysql游标错误
    is not writable or has an invalid setter method错误的解决
    Struts2中关于"There is no Action mapped for namespace / and action name"的总结
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/7429785.html
Copyright © 2011-2022 走看看