一页书的书
时间限制(普通/Java) : 1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 118 测试通过 : 37
总提交 : 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);
}
}
*/