题面:
解题:
显然,不太可能出现暴力枚举能过的黄题……
——嗅到了一点dp的味道,下求状态转移方程:
设dp[ i ][ j ]为选前i种花,一共要插j朵花的方法数,
那么,花的种数每增加1,我们都可以用一个变量k来表示新增加的这种花要摆放的数量,
对于新增加的第i种花,其数量上限题目已给出,记a,固第i种花的数量可能值 a ≥ k ≥ 0 ;
易得状态转移方程:dp[ i ][ j ]= dp[ i-1 ][ j-k ]
AC代码奉上
#include<iostream>
#include<algorithm>
using namespace std;
const int myMod = 1e6 + 7;
int n, m, a[1314]; //最喜欢的n种花 摆m盆花 数组范围随便取的……
long long dp[520][920] = { 0 }; //dp[i][j] i种花,一共j朵 的取法数
long long ans = 0;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> a[i];
for (int i = 0; i <= n; i++) //初始化边界
dp[i][0] = 1; //都取0朵,统一为1种方案
for(int i=1;i<=a[1]; i++) //初始化边界2
dp[1][i] = 1; //只取第一种花,数量为1~a[1]时,均为1种
for (int i = 2; i <= n; i++) //i种花,1~n
{
for (int j = 0; j <= m; j++) //j为花的总数,0~m
for (int k = 0; k <=a[i]; k++) //k为选取的新的一种花的数量,从0~a[i]
{
if (j + k == 0)continue;
dp[i][j + k] += dp[i - 1][j] % myMod;
dp[i][j + k] %= myMod;
}
}
cout << dp[n][m] % myMod << endl;
return 0;
}