排队[HNOI2012][Codevs1994]

原创 2016年06月01日 10:37:33

题目描述 Description

某中学有 n 名男同学, m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)


输入描述 Input Description

输入文件只有一行且为用空格隔开的两个非负整数 nm ,其含义如上所述。


输出描述 Output Description

仅包含一个非负整数,表示不同的排法个数。注意答案可能很大。


样例输入 Sample Input

样例输入 1

1 1

样例输入 2

7 3


样例输出 Sample Output

样例输出 1

12

样例输出 2

220631040


数据范围及提示 Data Size & Hint

对于 30% 的数据 n100,m100
对于 100% 的数据 n2000,m2000


分析

首先讨论特殊情况。
n=0 时,若 m=1ans=2 。若 m=2ans=8。否则 ans=0
m>n+3ans=0 (必定会有两个女生相邻)

一般情况。
我们把 n 个同学和 1 个老师站成一列,这样有 (n+1)! 种可能的情况,再讨论另一个老师站的地方。
1 :两个老师不站在一起,此时这个老师共有 n 个可能的位置。剩下的 m 个女生将会站在每两个同学(老师)中间的位置或队头,队尾共 n+3 个位置,根据排列我们知道共有 Amn+3 种可能,根据乘法原理我们知道两个老师不站在一起的合法方案数共 nAmn+3 种可能
2 :两个老师站在一起,这两个老师的位置共有 2 个可能(老师的前后顺序有两种可能),此时两个老师之间必定站着一个女生,共 m 种可能,剩下的 m1 个女生将会站在每两个同学(老师)中间的位置或队头,队尾共 n+2 个位置,根据排列我们知道共有 Am1n+2 种可能,根据乘法原理我们知道两个老师站在一起的合法方案数共 2mAm1n+2 种可能
综上,所有的可能情况有 (n+1)!(nAmn+3+2mAm1n+2) 种。因为数据大,所以要打高精度


代码

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;

const LL Mod = 100000000LL;

struct bignum{

    LL a[4000];
    int len;

    bignum(int num=0){
        memset(a,0,sizeof a);
        a[0] = num;
        len = 1;
    }

    bignum operator = (const bignum&h){
        memcpy(a,h.a,sizeof h.a);
        len = h.len;
        return *this;
    }

    bignum operator = (const int h){
        memset(a,0,sizeof a);
        a[0] = h;
        len = 1;
        return *this;
    }

    bignum operator * (const int h){
        bignum c;
        for(int i=0;i<len;++i)
            c.a[i] = a[i]*h;
        for(int i=0;i<len;++i){
            c.a[i+1] += c.a[i]/Mod;
            c.a[i] %= Mod;
        }
        if(c.a[len])
            c.len = len+1;
        else
            c.len = len;
        return c;
    }

    bignum operator * (const bignum h){
        bignum c;
        c.len = len+h.len;
        for(int i=0;i<len;++i)
            for(int j=0;j<h.len;++j)
                c.a[i+j] += a[i]*h.a[j];
        for(int i=0;i<c.len;++i){
            c.a[i+1] += c.a[i]/Mod;
            c.a[i] %= Mod;
        }
        if(!c.a[c.len-1])
            --c.len;
        return c;   
    }

    bignum operator + (const bignum h){
        bignum c;
        c.len = max(len,h.len);
        for(int i=0;i<c.len;++i){
            c.a[i] += a[i]+h.a[i];
            c.a[i+1] += c.a[i]/Mod;
            c.a[i] %= Mod;
        }
        if(c.a[c.len])
            ++c.len;
        return c;
    }

    void display(){
        printf("%lld",a[len-1]);
        for(int i=len-2;i>=0;--i)
            printf("%08lld",a[i]);
    }

}ans(1);

int n,m;

int main(){

    scanf("%d%d",&n,&m);

    if(!n){
        if(m == 1){printf("2");return 0;}
        else if(m == 2){printf("8");return 0;}
        else {printf("0");return 0;}
    }
    if(m > n+3){printf("0");return 0;}

    for(int i=2;i<=n+1;++i)
        ans = ans*i;

    bignum tmp1(n);
    for(int i=1;i<=m;++i)
        tmp1 = tmp1*(n+4-i);

    if(!m){
        ans = ans*tmp1;
        ans.display();
        return 0;
    }

    bignum tmp2(2*m);
    for(int i=1;i<=m-1;++i)
        tmp2 = tmp2*(n+3-i);

    ans = ans*(tmp1+tmp2);
    ans.display();

    return 0;

}
版权声明:本文为博主原创文章,未经博主允许不得转载。

CodeVS1994 排队

排列组合+高精度
  • FSAHFGSADHSAKNDAS
  • FSAHFGSADHSAKNDAS
  • 2017年03月02日 16:15
  • 124

[HNOI2012]排队

[HNOI2012]排队 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 608  Solved: 284 [Submit][Status]...
  • u012647218
  • u012647218
  • 2014年02月08日 13:19
  • 414

[BZOJ2729] [HNOI2012]排队

传送门题目大意n 名男同学,m 名女同学和两名老师排队,并且任意两名女同学不能相邻,两名老师也不能相邻,求方案数。题解先放n个男生有Ann种方案,然后再放2个老师,两个老师可以先挨着(中间用女生隔开)...
  • slongle_amazing
  • slongle_amazing
  • 2015年12月08日 23:35
  • 357

【BZOJ2729】[HNOI2012]排队【组合数学】

【题目链接】 还是python好用 【大爷的题解】 def A(n): res = 1 for i in range(1, n + 1): res *= i return res d...
  • BraketBN
  • BraketBN
  • 2016年05月26日 17:24
  • 147

[BZOJ2729][HNOI2012]排队

原题地址高精度一次写对辣!开心!然而公式推错,怒WA,感觉没救了…给用Python的跪了…...
  • Zvezda_
  • Zvezda_
  • 2015年09月21日 18:16
  • 228

2729: [HNOI2012]排队

题目链接题目大意:某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)...
  • Mmh2000
  • Mmh2000
  • 2017年08月21日 19:52
  • 94

BZOJ P2729: [HNOI2012]排队

两种做法 第一种:可能会萎掉DP f[i][j][k][k2]还剩下i个男孩,还剩下j个女孩时,还剩下k个老师时前面一个是k2(0:男/1:女/2:老师)的方案数 但是内存是6000*6000的...
  • mdnd1234
  • mdnd1234
  • 2017年03月11日 21:20
  • 87

【bzoj2729】[HNOI2012]排队

组合数学,高精度
  • KikiDMW
  • KikiDMW
  • 2017年04月02日 22:12
  • 104

bzoj2729: [HNOI2012]排队

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2729 思路:简单的排列组合题 A(n,n)*(A(n+1,2)*A(n+3,m)+A(m...
  • thy_asdf
  • thy_asdf
  • 2016年01月01日 10:38
  • 740

【BZOJ 2729】 [HNOI2012]排队

排列组合+python~
  • Regina8023
  • Regina8023
  • 2015年03月17日 17:40
  • 782
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:排队[HNOI2012][Codevs1994]
举报原因:
原因补充:

(最多只允许输入30个字)