【BZOJ2729】[HNOI2012]排队 组合数

【BZOJ2729】[HNOI2012]排队

Description

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

Input

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

对于 30%的数据 n≤100,m≤100

对于 100%的数据 n≤2000,m≤2000

Output

输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数。注意答案可能很大。

Sample Input

1 1

Sample Output

12

题解:先将老师与男生放到一起,然后将女生插到男生中间,方案书就是A(n+2,n+2)*A(n+3,m),再将老师相邻的方案减去,即将两个老师捆在一起,方案数为A(2,2)*A(n+1,n+1)*A(n+2,m)。

然后就是丧心病狂的高精度时间了。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
struct cbig
{
	int len;
	int v[200000];
	cbig(){len=0,memset(v,0,sizeof(v));}
	cbig(int x)
	{
		len=0,memset(v,0,sizeof(v));
		while(x)	v[++len]=x%10,x/=10;
	}
	void operator *= (int b)
	{
		int i;
		for(i=1;i<=len;i++)	v[i]*=b;
		for(i=1;i<=len;i++)	v[i+1]+=v[i]/10,v[i]%=10;
		while(v[len+1])	len++,v[len+1]+=v[len]/10,v[len]%=10;
	}
	void operator -= (cbig b)
	{
		int i;
		for(i=1;i<=b.len;i++)	v[i]-=b.v[i];
		for(i=1;i<=len;i++)
		{
			if(v[i]<0)	v[i+1]+=v[i]/10,v[i]%=10;
			if(v[i]<0)	v[i+1]--,v[i]+=10;
		}
		while(len&&!v[len])	len--;
	}
}ans1,ans2;
void A(cbig &ret,int a,int b)
{
	for(int i=a-b+1;i<=a;i++)	ret*=i;
}
int main()
{
	int i,n,m;
	scanf("%d%d",&n,&m);
	ans1=cbig(1),A(ans1,n+2,n+2),A(ans1,n+3,m);
	ans2=cbig(2),A(ans2,n+1,n+1),A(ans2,n+2,m);
	ans1-=ans2;
	if(!ans1.len)	printf("0");
	else	for(i=ans1.len;i;i--)	printf("%d",ans1.v[i]);
	return 0;
}
时间: 2024-10-24 23:04:45

【BZOJ2729】[HNOI2012]排队 组合数的相关文章

bzoj2729: [HNOI2012]排队

高精度+排列组合. 如果计算老师能挨在一起的情况 有 (n+2)! * A(n+3,m) 老师一定挨宰一起的情况 有 2*(n+1)!*A(n+2,m). 相减就是答案. #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 3000; const int mod = 10000; struct bigint { int a[maxn+10

2729: [HNOI2012]排队

2729: [HNOI2012]排队 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 957  Solved: 449[Submit][Status] Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) Input 只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述. 对于 30%

【BZOJ2729】【HNOI2012】排队 组合数 数论 Python高精度

转载请注明出处谢谢:http://blog.csdn.net/vmurder/article/details/42964151 题解: 代码里面有注释. 注意: Python2中的中文字符即使注释了,也会CE(当然,因为Python是直接运行,不编译,所以显示WA) 呃,而本地的Python3就不管它了.. 所以我的代码需要删掉中文注释再交233. 代码: # n!(A(n+1,2)*A(n+3,m)+2*(n+1)*A(n+2,m-1)*m) # 首先男生随便放 这样是n!种摆法. # 然后再

[BZOJ 2729][HNOI2012]排队(排列组合+高精)

Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) Solution 好像必须写压位高精的QAQ 先排n名男生,插空,讨论两名老师插在两个不同的空里的情况和先排在一起再在中间插一名女生的情况 #include<iostream> #include<cstdio> #include<cstring> #include&

[HNOI2012]排队

Description 某中学有 n 名男同学,m 名女同学和两名老师要排队参加体检.他们排成一条直线,并且任意两名女同学不能相邻,两名老师也不能相邻,那么一共有多少种排法呢?(注意:任意两个人都是不同的) Input 只有一行且为用空格隔开的两个非负整数 n 和 m,其含义如上所述. 对于 30%的数据 n≤100,m≤100 对于 100%的数据 n≤2000,m≤2000 Output 输出文件 output.txt 仅包含一个非负整数,表示不同的排法个数.注意答案可能很大. Sample

【BZOJ】2729: [HNOI2012]排队

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2729 先考虑放好男生,一共有:${n!}$种放法. 然后分情况考虑老师的放法: 1.如果两个老师放在了相同两个男生之间:${m*A_{n+1}^{1}*A_{n+2}^{m-1}}$ 2.如果分开放:${A_{n+1}^{2}*A_{n+3}^{m}}$ 最后答案分别与${n!}$相乘再相加即可. HNOI居然会考送肉组合数学裸题... python大发好!

BZOJ 2729 HNOI2012 排队 组合数学

题目大意:给定n个男生m个女生两个老师,求有多少种排列满足任意两个女生不相邻,任意两个老师也不相邻 def A(n): re=1 for i in range(1,n+1): re*=i return re def C(n,m): if n<m: return 0 return A(n)//A(m)//A(n-m) n,m=[int(i) for i in raw_input().split()] print m*A(n+1)*2*A(m-1)*C(n+2,m-1)+(A(n+2)-A(n+1)

【BZOJ】【2729】【HNOI2012】排队

排列组合+高精度 Orz PoPoQQQ 引用题解: 嗯……学习了一下python= =懒的写高精了 1 /************************************************************** 2 Problem: 2729 3 User: Tunix 4 Language: Python 5 Result: Accepted 6 Time:832 ms 7 Memory:6360 kb 8 ********************************

[uva11174]村民排队 递推+组合数+线性求逆元

n(n<=40000)个村民排成一列,每个人不能排在自己父亲的前面,有些人的父亲不一定在.问有多少种方案. 父子关系组成一个森林,加一个虚拟根rt,转化成一棵树. 假设f[i]表示以i为根的子树的排列方案数. f[i]=f[1]*f[2]*..f[k] /(sum[i]-1)!/sum[1]!*sum[2]!*..sum[k]!) 化简,对每一个i,sum[i]-1在分子出现一次,sum[i]在分母出现一次. Ans = n!/(sum1*sum2*sum3*...*sumn) 1 #inclu