标签:class res 不同的 输出 names ted 个数 范围 stream
终于解出了dm同学的难题,dm同学同意帮v神联络。可dm同学有个习惯,就是联络同学的时候喜欢分组联络,而且分组的方式也很特别,要求第i组的的人数必须大于他指定的个数ci。在dm同学联络的时候,v神在想,按照dm同学的规则一共可以有多少种方案呢?他想啊想,终于……没想出来。于是他又想到了聪明的你,你能帮v神算出按照dm同学的规则有多少种分组方案吗?
v神的班级共有n个人,dm同学想把同学分成M组联络,要求第i组的人数必须大于给定的正整数Ci,求有多少不同的方案?(两个是相同的方案当且仅当对于任意的一队i,两个方案的第i组同学数量相等)由于结果很大,所以你只需要输出模1000000007的值。
输入格式:
第一行两个整数N和M ,后面有M行,每行一个整数,表示Ci
输出格式:
仅有一行,一个整数,方案数模1000000007的值。
样例解释:
方案有三种,每组的个数分别是(3,3,4),(2,4,4),(2,3,5)。
数据范围约定:
对于30%的数据,N ,M<= 10
对于60%的数据,N ,M<=1000
对于100%的数据,N ,M<= 1000000 Ci<=1000
数据保证至少有一个方案
隔板法
不会的请进:http://baike.sogou.com/v10001101.htm?fromTitle=%E6%8F%92%E6%9D%BF%E6%B3%95
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 1000100 #define ll long long #define mod 1000000007 using namespace std; long long ans; int n,m,a[N],jie[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } ll qpow(ll a,ll b,int p) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p,b>>=1; }return res; } ll C(ll n,ll m,int p) { if(m>n) return 0; return jie[n]*qpow(1ll*jie[n-m]*jie[m]%p,p-2,p)%p; } ll Lus(ll n,ll m,int p) { if(m==0) return 1; return Lus(n/p,m/p,p)*C(n%p,m%p,p)%p; } int main() { n=read();m=read(); for(int i=1;i<=m;i++) a[i]=read(); for(int i=1;i<=m;i++) n-=a[i];jie[0]=1; for(int i=1;i<=n;i++) jie[i]=1ll*jie[i-1]*i%mod; ans=Lus(n-1,m-1,mod); printf("%lld",ans); return 0; }
标签:class res 不同的 输出 names ted 个数 范围 stream
原文地址:http://www.cnblogs.com/z360/p/7905859.html