第六次訓練

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);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章