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;
    } 
    



  • 相关阅读:
    分页参数处理逻辑的最佳实践
    浅谈软件界面设计原则
    Django 页面缓存的cache_key是如何生成的
    mvn 命令上传 jar 包到 nexus 私仓
    知 识 收 录
    JavaScript 使用Map对象
    windows bat脚本守护java进程
    ubuntu java启动shell脚本
    Linux cron定时任务启动jar程序
    ubuntu java调用海康sdk报错Unable to load library '/home/bjlthy/HCNetSDK/libPlayCtrl.so'
  • 原文地址:https://www.cnblogs.com/zhumengdexiaobai/p/7429785.html
Copyright © 2011-2022 走看看