比赛描述
一页书前辈作为一位得道高僧,在他无悔的生涯中创作了许多经典,被世人称作百世经纶。这一天有m个粉丝来膜拜书大,书大很开心,决定送他们每人一本经典。已知一页书一共创作了n部作品,每部作品分别有a1、a2…an份藏本,那么书大一共可以有多少种送书的选择呢?(由于计算结果可能很大,请把结果对1000000007取模)
输入
第一行是一个正整数T表示有T组数据
每组数据第一行是两个正整数n,m(n,m<=20)
第二行是n个正整数ai(ai<=20)
输出
一个正整数k表示方法的总数对1000000007(10^9+7)取模的结果
样例输入
2
2 3
2 2
2 3
3 3
样例输出
6
8
题目来源
LY:D
#include<iostream> #define N 21 #define MOD 1000000007 int a[N]; __int64 c[N][N]; __int64 dp[N][N]; int main(){ freopen("test.txt","r",stdin); int t,n,m,i,j,k; scanf("%d",&t); for(i=0;i<N;i++){ c[i][0] = 1; } for(i=1;i<N;i++){ //WA i=1 for(j=1;j<=i;j++){ c[i][j] = (c[i-1][j-1]+c[i-1][j])%MOD; //WA c[i-1][j-1]+c[i-1][j] } } while(t--){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ //WA i<=n scanf("%d",a+i); //WA %I64d } memset(dp,0,sizeof(dp)); for(i=0; i<=m&&i<=a[1]; i++){ //WA i<=a[1] dp[i][1] = 1; } for(i=0;i<=m;i++){ //WA i=0 错误在于:dp[0][0]=0,其他任意j>=1,dp[0][j]=1 for(j=2;j<=n;j++){ //WA j=2 或者 j=1 都行 for(k=0; k<=a[j]&&k<=i; k++){ dp[i][j] = (dp[i][j]+c[i][k]*dp[i-k][j-1])%MOD; } } } printf("%I64d\n",dp[m][n]); } } /* AC #include<iostream> #define N 21 #define MOD 1000000007 int n,m; int a[N]; __int64 c[N][N]; __int64 dp[N][N]; void init(){ int i,j; memset(c, 0, sizeof(c)); for(int i = 0; i < 21; i++) c[i][0] = 1; for(i=1;i<21;i++){ for(j=1;j<21; j++){ c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % MOD; } } } void dynamicProgram(){ int i,j,k; __int64 temp; for(i=0;i<=m && i<=a[1];i++){ dp[i][1] = 1; } for(int i = 0; i <= m; i++) for(int j = 1; j <= n; j++) for(int k = 0; k <= a[j] && k<= i; k++) dp[i][j] = (dp[i][j]+ c[i][k] * dp[i - k][j - 1] % MOD) % MOD; } int main(){ freopen("test.txt","r",stdin); int T,i; init(); scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(i=1;i<=n;i++){ scanf("%d",a+i); } memset(dp, 0, sizeof(dp)); dynamicProgram(); printf("%I64d\n",dp[m][n]); } } */ /*Time Limit Exceed at Test 1 #include<stdio.h> #define MOD 1000000007 #define N 21 int n,m; __int64 a[N],count,factorial[N]; void handle(int i){ int j; if(i==m){ for(j=1;j<=n;j++){ if(a[j]>0){ count = (count+1)%MOD; } } return; } for(j=1;j<=n;j++){ if(a[j]>0){ a[j]--; handle(i+1); a[j]++; } } } int main(){ // freopen("text.txt","r",stdin); int T,i; factorial[0] = 1; for(i=1,T=1;i<N;i++){ T = T*i%MOD; factorial[i] = T; } scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); count = 0; for(i=1;i<=n;i++){ scanf("%I64d",a+i); } handle(1); printf("%I64d\n",count); } } */