P2638 安全系统

LLink
本代码没有高精。
首先很容易想到的是,0,1之间互相并不干扰,所以说我们只要分开算0和1的方案数乘起来就可以了。
那么怎么算方案数呢?
首先可以想到的一点就是,如果我们确定了要放\(a\)个1的话,只要采用隔板法就可以确定了方案书。
有的可以没有怎么办?先给每一个隔间都放上一个球,答案就是\(C_{a+n}^{n-1}\)
所以\(ans=\sum_{i=0}^a\sum_{j=0}^bC_{i+n}^{n-1}C_{j+n}^{n-1}\)
如果我们想化简一下呢?考虑又多出来一个垃圾箱,然后放到垃圾箱里的数字没有任何用处。
这样对于单个数字,答案就可以化简为\(C_{a+n}^{n}\)
就可以快速计算了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<ctime>
#include<bitset>
#define ll unsigned long long
using namespace std;
ll a,b,n;
ll cal(ll n,ll m){
	ll ans=1;
	for(int i=1;i<=n;++i){
		ans*=m-i+1;
		ans/=i;
	}
	return ans;
}
ll ans;
int main(){
	cin>>n>>a>>b;
	printf("%llu",cal(n,n+a)*cal(n,n+b));
	return 0;
}

其中为什么那样计算的时候是可以的呢?考虑一下当你除\(i\)的时候,是不是已经乘了\(i\)个数了?

posted @ 2023-09-16 22:07  Simex  阅读(9)  评论(0编辑  收藏  举报