2108: 摆花
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 50 Solved: 34
[Submit][Status][Web Board]
Description
小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆。通过调查顾客的喜好,小明列出了顾客最喜欢的n种花,从1到n标号。为了在门口展出更多种花,规定第i种花不能超过ai盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。
试编程计算,一共有多少种不同的摆花方案。
Input
第一行包含两个正整数n和m,中间用一个空格隔开。
第二行有n个整数,每两个整数之间用一个空格隔开,依次表示a1、a2、……an。
Output
输出只有一行,一个整数,表示有多少种方案。注意:因为方案数可能很多,请输出方案数对1000007取模的结果。
Sample Input
2 4
3 2
Sample Output
2
HINT
对于100%数据,有0<n≤100,0<m≤100,0≤ ai≤100。
Source
解题思路:
动态规划题。令a[i]为第i种花的数量,f[i][j]表示前i种花摆放j盆的摆放方案,对于第i种花可以使用0,1,2……a[i]盆,对应的前i-1种花摆放的盆数为j-0,j-1,j-1……j-a[i] ,即f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-1][j-2]+...+f[i-1][j-a[i]] =f[i-1][j-k](0<=k<=a[i],j>=k)
初始值为f[1][0]=1,f[1][1]=1,...f[1][a[1]]=1; 即第一种花摆放0,1,2……a[1]的摆放方案为1种。
代码:
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
int main()
{
int n,m;
int i,j,f[200][200];
cin>>n>>m;
int a[n+1];
for(i=1;i<=n;i++)cin>>a[i];
memset(f,0,sizeof(f));
for(i=0;i<=a[1];i++)
f[1][i]=1;
for(i=2;i<=n;i++){
for(j=0;j<=m;j++){
for(int k=0;k<=a[i];k++)
if(j>=k)f[i][j]=(f[i][j]+f[i-1][j-k])%1000007;
}
}
cout<<f[n][m]<<endl;
return 0;
}