bzoj 4710 : [Jsoi2011]分特产
2017-02-26 21:58
281 查看
好久没做组合的题竟然懵逼了好长时间,去吃了顿饭就突然会做了。。。
如果没有每个人至少一个的限制的话那么答案显然是∏(c(n-1,a[i]+n-1)),相当于把每一种物品排成一排然后每排放(n-1)个隔板,第i个隔板和第i+1个隔板之间的物品就是第i个人的物品,显然每种方案对应着一种实际方案(会组合的人就当我是在废话吧)。
那么如果加上限制呢,第一反应显然是容斥,上一段算出的答案可能有一个人没有,那就减去n-1个人的所有合法方案(没有空的人)*n(枚举谁没有),如果有两个人没有那就减去n-2个人的合法方案*c(n,2),这东西显然可以递推,那就做完了。
如果没有每个人至少一个的限制的话那么答案显然是∏(c(n-1,a[i]+n-1)),相当于把每一种物品排成一排然后每排放(n-1)个隔板,第i个隔板和第i+1个隔板之间的物品就是第i个人的物品,显然每种方案对应着一种实际方案(会组合的人就当我是在废话吧)。
那么如果加上限制呢,第一反应显然是容斥,上一段算出的答案可能有一个人没有,那就减去n-1个人的所有合法方案(没有空的人)*n(枚举谁没有),如果有两个人没有那就减去n-2个人的合法方案*c(n,2),这东西显然可以递推,那就做完了。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define ll long long #define N 2005 using namespace std; int read() { int p=0;char c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')p=p*10+c-'0',c=getchar(); return p; } const int p = 1000000007; int c ; void yu() { for(int i=0;i<=2000;i++) { c[i][0]=1; for(int j=1;j<=i;j++) { c[i][j]=(c[i-1][j-1]+c[i-1][j])%p; } } return ; } int n,m; int a ; int f ; int main() { scanf("%d%d",&n,&m); yu(); for(int i=1;i<=m;i++)scanf("%d",&a[i]); for(int i=1;i<=n;i++) { f[i]=1; for(int j=1;j<=m;j++) { f[i]=((ll)f[i]*c[a[j]+i-1][i-1])%p;; } for(int j=1;j<i;j++) { f[i]=(f[i]-((ll)f[j]*c[i][i-j])%p+p)%p; } } printf("%d\n",f ); return 0; }
相关文章推荐
- bzoj 4710: [Jsoi2011]分特产 (容斥原理+DP)
- bzoj4710 [Jsoi2011]分特产 容斥原理
- [Jsoi 2011] bzoj4710 分特产 [容斥原理+组合数学]
- BZOJ 4710: [Jsoi2011]分特产 [容斥原理]
- [BZOJ4710]4710: [Jsoi2011]分特产 容斥原理+组合数学
- bzoj千题计划273:bzoj4710: [Jsoi2011]分特产
- ●BZOJ 4710 [Jsoi2011]分特产
- 【BZOJ 4710】【JSOI 2011】分特产【计数&容斥】
- Bzoj4710--Jsoi2011分特产
- bzoj 4710: [Jsoi2011]分特产 排列组合+容斥原理
- [BZOJ4710][JSOI2011]分特产(组合数+容斥原理)
- Bzoj4710 [Jsoi2011]分特产
- 【BZOJ4710】[Jsoi2011]分特产 组合数+容斥
- [bzoj4710][JSOI2011]分特产
- bzoj 4710: [Jsoi2011]分特产
- 【bzoj4710】[Jsoi2011]分特产 容斥原理+组合数学
- [BZOJ4710][JSOI2011]分特产(组合数学+容斥原理)
- [BZOJ4710][Jsoi2011]分特产(容斥原理+组合数学)
- bzoj 4710: [Jsoi2011]分特产
- bzoj 4710 [Jsoi2011]分特产