1. 程式人生 > >擺花(codevs 1315)

擺花(codevs 1315)

dp問題 div can %d 輸出 估計 一個 class 收獲

題目描述 Description

小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。為了在門口展出更多種花,規定第i種花不能超過ai盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。

試編程計算,一共有多少種不同的擺花方案。

輸入描述 Input Description

輸入共2行。

第一行包含兩個正整數n和m,中間用一個空格隔開。

第二行有n個整數,每兩個整數之間用一個空格隔開,依次表示a1、a2、……an。

輸出描述 Output Description

輸出只有一行,一個整數,表示有多少種方案。註意:因為方案數可能很多,請輸出方案數對1000007取模的結果。

樣例輸入 Sample Input

2 4

3 2

樣例輸出 Sample Output

2

數據範圍及提示 Data Size & Hint

【輸入輸出樣例說明】

有2種擺花的方案,分別是(1,1,1,2),(1,1,2,2)。括號裏的1和2表示兩種花,比如第一個方案是前三個位置擺第一種花,第四個位置擺第二種花。

【數據範圍】

對於20%數據,有0<n≤8,0<m≤8,0≤ai≤8;

對於50%數據,有0<n≤20,0<m≤20,0≤ai≤20;

對於100%數據,有0<n≤100,0<m≤100,0≤ai≤100。


通過這道題,我認為最大的收獲是弄清了倒推的意義。之前一直都是看題解,瞬時記憶做法,但並沒有真正掌握。現在,我估計初步有了獨立思考DP問題的能力了

思路:

當前的狀態是由上一步的方程直接推出,我們在推出當前狀態時需要維護之前狀態,因此采用倒推,利用之前的狀態先改變後面的狀態,逐步向前推去

如果後邊還要推方程,那就為後面的結論做好了鋪墊;如果已經到頭了,那就已經求出答案啦

詳見代碼^-^

#include<stdio.h>
#define MX 1001
#define P 1000007
int a[MX],f[MX];

int main()
{
    int n,m;
    scanf("%d%d",&n,&m); //n=2,m=4
    for(int i=1;i<=n;++i) {
        scanf(
"%d",&a[i]); } f[0]=1; for(int i=1;i<=n;++i) //i 種花 for(int j=m;j>=1;j--)//擺 j 盆 for(int k=1;k<=j && k<=a[i];++k)//第 i 種花擺 k 盆 f[j]=(f[j]+f[j-k])%P;//更新結果擺 j 盆花的情況 printf("%d",f[m]); return 0; }

擺花(codevs 1315)