C 擺花
題目描述
小明的花店新開張,爲了吸引顧客,他想在花店的門口擺上一排花,共 m 盆。
通過調 查顧客的喜好,小明列出了顧客最喜歡的 n 種花,從 1 到 n 標號。
爲了在門口展出更多種花, 規定第 i 種花不能超過 ai盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到 大的順序依次擺列。
試編程計算,一共有多少種不同的擺花方案。
輸入
第一行包含兩個正整數 n 和 m,中間用一個空格隔開。
第二行有 n 個整數,每兩個整數之間用一個空格隔開,依次表示 a1、a2、……an。
輸出
輸出只有一行,一個整數,表示有多少種方案。
注意:因爲方案數可能很多,請輸出 方案數對 1000007 取模的結果。
樣例輸入
2 4 3 2
樣例輸出
2
提示
【輸入輸出樣例說明】
有 2 種擺花的方案,分別是(1,1,1,2), (1,1,2,2)。
括號裏的 1 和 2 表示兩種花, 比如第一個方案是前三個位置擺第一種花,第四個位置擺第二種花。
這是一個DP的題目,我們用一個二維數組記錄即可,一維數組a[i]表示每種花有多少個。
ans[i][j]表示選了前i種花共j個,當前的第i種可以選0到a[i]個,因爲也可以不選這種花,那麼我們就可以得出狀態轉移方程
ans[i][j]=ans[i][j]+ans[i-1][j-k] (ans[i-1][j-k]表示前i-1種選了j-k個)
需要注意的是ans[0][0]一開始要初始化爲1,因爲第一種花一個也不選也是一種情況。
#include<bits/stdc++.h>
#define exp 1e-8
#define mian main
#define pii pair<int,int>
#define pll pair<ll,ll>
#define ll long long
#define pb push_back
#define PI acos(-1.0)
#define inf 0x3f3f3f3f
#define w(x) while(x--)
#define int_max 2147483647
#define lowbit(x) (x)&(-x)
#define gcd(a,b) __gcd(a,b)
#define pq(x) priority_queue<x>
#define ull unsigned long long
#define sc(x) scanf("%d",&x)
#define scl(x) scanf("%lld",&x)
#define pl(a,n) next_permutation(a,a+n)
#define ios ios::sync_with_stdio(false)
#define met(a,x) memset((a),(x),sizeof((a)))
#define mod 1000007
using namespace std;
int ans[110][110],n,m,a[110];
int main()
{
while(~scanf("%d%d",&n,&m))
{
met(ans,0);
for(int i=1;i<=n;i++)
sc(a[i]);
ans[0][0]=1; //第一種花選0個也是一種方案
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=a[i];k++)
if(j>=k){
ans[i][j]+=ans[i-1][j-k];
ans[i][j]%=mod;
}
printf("%d\n",ans[n][m]%mod);
}
}