擺花(codevs 1315)
阿新 • • 發佈:2018-08-11
dp問題 div can %d 輸出 估計 一個 class 收獲
樣例輸入 Sample Input
題目描述 Description
小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。為了在門口展出更多種花,規定第i種花不能超過ai盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。
試編程計算,一共有多少種不同的擺花方案。
輸入描述 Input Description輸入共2行。
第一行包含兩個正整數n和m,中間用一個空格隔開。
第二行有n個整數,每兩個整數之間用一個空格隔開,依次表示a1、a2、……an。
輸出描述 Output Description輸出只有一行,一個整數,表示有多少種方案。註意:因為方案數可能很多,請輸出方案數對1000007取模的結果。
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)