南邮 OJ 2033 一页书的书

一页书的书

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 118            测试通过 : 37 

比赛描述

一页书前辈作为一位得道高僧,在他无悔的生涯中创作了许多经典,被世人称作百世经纶。这一天有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);
	}
}
*/


你可能感兴趣的:(ACM,南邮OJ,一页书的书)