zoukankan      html  css  js  c++  java
  • 完全错排问题

    题目链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=451

    就是求C(n, n-m)*s(m)的值啦,C(n, n-m)表示从n个人中任取n-m个人的组合数,s(m)表示m对人和纸条的完全错排种数;

    组合数求法很简单就不细说了,推一下完全错排计算公式好了;

    假设现在有编号1~m的m个求和编号1~m的m个盒子,将m个求均分到m个盒子中,且1号球不能放1号盒子,2号球不能放2号盒子。。。(m个球完全错排);

    用s(m)表示m个球的完全错排方法数;

    假设先放1号球,可以放编号2~m的盒子,有m-1种放法(先放任意编号的球都是一样的),假设后面m-1个球有a中放法,则s(m)=(m-1)*a;

    假设1号球放在2号盒子里,接下来我们考虑:

      (1):假设2号球放在1号盒子里,剩余的球有s(m-2)种放法;

      (2):假设2号球不放1号盒子里,这时我们可以将1号盒子和2号盒子换下位子,(因为2号球不放1号盒子,所以我们可以把1号盒子当做2号盒子来看,这点比较难理解但很关键),

         于是我们可以得到剩余的球有s(m-1)种放法;

    所以a=s(m-1)+s(m-2);

    即:s(m)=(m-1)*(s(m-1)*s(m-2);

    代码:

     1 #include <bits/stdc++.h>
     2 #define MAXN 20+10
     3 #define ll long long
     4 using namespace std;
     5 
     6 ll cc(ll n, ll m){
     7     ll ans=1; 
     8     for(ll i=n, k=1; k<=m; k++, i--){
     9         ans*=i;
    10     }
    11     for(int i=1; i<=m; i++){
    12         ans/=i;
    13     }
    14     return ans;
    15 }
    16 
    17 int main(void){
    18     ll n, m, a[MAXN];
    19     a[2]=1, a[3]=2;
    20     for(int i=4; i<MAXN; i++){
    21         a[i]=(i-1)*(a[i-1]+a[i-2]);
    22     }
    23     while(scanf("%lld%lld", &n, &m)!=EOF){
    24         ll ans=cc(n, n-m)*a[m];
    25         cout << ans << endl;
    26     }
    27     return 0;
    28 }
  • 相关阅读:
    docker 命令(我使用过的)
    docker 概述
    RabbitMq 概述
    spring cloud gateway
    redis-集群(codis和Cluster)
    jdbc 简单示例和优缺点
    git
    Mycat--概述
    线程池
    同步容器和并发容器
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/5943953.html
Copyright © 2011-2022 走看看