zoukankan      html  css  js  c++  java
  • P3223 [HNOI2012]排队

    题目描述

    某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检。他们排成一条直线,并且任意两名女同学不能相邻,

    两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的)

    输入格式

    只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述。

    输出格式

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

    输入输出样例

    输入 #1

    1 1

    输出 #1

    12

    说明/提示

    对于 30% 的数据 \(n\leq 100\)

    对于 100% 的数据 \(n\leq 2000\)

    这道题的柿子好难啊(蒟蒻我只能爬

    首先,我们分两种情况讨论

    1. 当两个老师之间是男生的时候。 这还是很简单的

      首先先将\(n\)个男生排好队就是 \(A_{n}^{n}\)

      此时产生了\(n+1\)个空,把两位老师插进去就有\(A_{n+1}^{2}\)种方案

      然后就会产生\(n+3\)个空 再把\(m\)个女生放进去就会有\(A_{n+3}^{m}\)种方案

      那么综上第一种情况会有\(A_{n}^{n} \times A_{n+1}^{2} \times A_{n+3}^{m}\)

    2. 当由女生把老师隔开的时候,这种情况比较复杂,需要我们大力讨论

      首先,因为这个不管男生什么事,那我们就可以先把男生先排好也就是\(A_{n}^{n}\)

      然后,因为老师之间要是女生,所以我们可以把两个老师和一个女生当成一个整体,

      插入到\(n+1\)个空中,因为老师之间又是不同的,所以可以产生\(A_{2}^{2}\)种不同的排法

      再加上从\(m\)个女生中选出一个的方案数为\(C_{m}^{1}\),就会有\(A_{n+1}^{1} \times A_{2}^{2} \times C_{m}^{1}\)

      至于剩下的\(m-1\)个女生直接插在\(n+2\)个空中就可以了,也就会产生\(A_{n+2}^{m-1}\)种方案

      综上第二种情况的方案数就为\(A_{n}^{n} \times A_{n+1}^{1} \times A_{2}^{2} \times C_{m}^{1} \times A_{n+2}^{m-1}\)

    最后的答案就是\(A_{n}^{n} \times A_{n+1}^{2} \times A_{n+3}^{m} + A_{n}^{n} \times A_{n+1}^{1} \times A_{2}^{2} \times C_{m}^{1} \times A_{n+2}^{m-1}\)

    这个柿子其实还是可以化简的,但是我忘了怎么化了(大雾

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    long long n,m,len = 1;
    long long ans[11000];
    long long p = 100000000;
    void mul(int x){
    	long long res = 0,num;
    	for(int i = 1; i <= len; i++){
    		num = ans[i] * x;
    		ans[i] = num % p + res;
    		res = num / p;//进位 
    	}
    	if(res != 0){
    		len++;
    		ans[len] = res;
    	}
    }
    int main(){
    	scanf("%lld%lld",&n,&m);
    	ans[1] = 1;
    	mul(n+1);
    	mul(n*n+3*n+2*m);
    	for(int i = 1; i <= n; i++){//计算n的阶乘 
    		mul(i);
    	}
    	for(int i = n-m+4; i <= n+2; i++){//计算n+2的阶乘除以n-m+3的阶乘 
    		mul(i);
    	}
    	cout<<ans[len];
    	while(--len){
    		printf("%08lld",ans[len]);
    	}
    	return 0;
    }
    //拜托不要卡cincout 远古时期的代码
    
    
  • 相关阅读:
    第一册:lesson thirty five。
    第一册:lesson thirty three。
    第一册:lesson thirty one。
    C#比较两个对象是否为同一个对象。
    第一册:lesson twentynine..
    第一册:lesson twenty seven。
    C#函数返回值。
    说明
    推荐一些python Beautiful Soup学习网址
    祝各位节日快乐!20151111
  • 原文地址:https://www.cnblogs.com/genshy/p/13498115.html
Copyright © 2011-2022 走看看