題目描述
小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。為了在門口展出更多種花,規定第i種花不能超過ai 盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。
試程式設計計算,一共有多少種不同的擺花方案。
輸入格式
第一行包含兩個正整數n和m,中間用乙個空格隔開。
第二行有n個整數,每兩個整數之間用乙個空格隔開,依次表示a1,a2,…,an
輸出格式
乙個整數,表示有多少種方案。注意:因為方案數可能很多,請輸出方案數對1000007取模的結果。
輸入輸出樣例
輸入2 4
3 2輸出
2說明/提示
【資料範圍】
對於20%資料,有0對於50%資料,有0對於100%資料,有0我一開始想的是dp[i][j]
表示已經擺了i
盆花,最後擺的花種類為j
的方案總數,則最後答案為dp[n][1...m](累加)
(這裡定義的n為盆數,m為種數)
這樣的狀態很麻煩。
我們需要:
一層for遍歷擺的盆數 i
二層for遍歷結尾擺的種類 j
三層for遍歷 j 種類擺的盆數 k (k從1開始,不能從0開始,因為已經規定了最後種類為 j )
四層for遍歷 該種類在 l (1<=l<=j-1) 後面 (設j=4
,可以考慮到前乙個種類是1,2,3
)
#include
#include
#include
#define ll long long
using
namespace std;
const
int mod =
1000007
;int
main()
}}} ll ans =0;
for(
int i =
1;i <= m;i++
) ans =
(ans+dp[n]
[i])
%mod;
printf
("%lld\n"
,ans)
;return0;
}
這種時間複雜度很高,但是樣例比較水還是ac了。我們試著優化一下。
我們發現第四層迴圈其實就是dp[i][j] + dp[i-k][1...j-1]
,這其實就是字首和。那麼我們可以定義sum[i][j]
表示擺了i盆花,最後擺的花種類為[1…j]的的方案總數,則我們最終求得答案就是sum[n][m]
(n為個數,m為種類)
#include
#include
#include
#define ll long long
using
namespace std;
const
int mod =
1000007
;int
main()
sum[i]
[j]=
(sum[i]
[j-1
]+dp[i]
[j])
%mod;
//更新字首和 }}
printf
("%lld\n"
,sum[n]
[m])
;return0;
}
這樣優化後n,m取最大也能ac.
這種狀態寫起來是麻煩的。如果將狀態定義為:
dp[i][j]
表示在前 n 種花,當前已有 j 盆的方案總數,那麼最後結果就是dp[n][m]
(n為種數,m為個數)
第一層for遍歷種類 i
第二層for遍歷個數 j ( j 從0開始,因為第一盆可以從2~n起始)
第三層for遍歷第 i 種選擇放的個數 k ( k 從0開始,設 i = 2, 可以考慮有 [1,3]這種情況)
dp[i][j] = (dp[i][j]+dp[i-1][j-k])%mod
#include
#include
#include
using
namespace std;
intmain()
}}printf
("%lld\n"
,dp[n]
[m])
;return0;
}
可以像01揹包一樣優化一下空間。
我們發現dp[i][j]
的更新只和dp[i-1][x](x<=j)
層有關係,這和01揹包的情況是一樣的,因此可以滾動陣列優化。
#include
#include
#include
using
namespace std;
intmain()
}}printf
("%lld\n"
,dp[m]);
return0;
}
P1077 擺花 揹包DP
小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。為了在門口展出更多種花,規定第iii種花不能超過 a i 盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。試程式設計計算,一共有多少種不同的...
擺花 01揹包
p1077 noip2012 普及組 擺花 洛谷 電腦科學教育新生態 luogu.com.cn 很很很基礎的一道01揹包問題,但是對目前的我來說還是有亮點的。狀態表示 前i種花共j盆的擺放方案數量 狀態計算 1.如果第i種花不擺 f i,j f i 1,j 2.如果第i種花擺 遍歷第i種花能擺放擺放...
洛谷P1077 擺花 揹包dp
小明的花店新開張,為了吸引顧客,他想在花店的門口擺上一排花,共m盆。通過調查顧客的喜好,小明列出了顧客最喜歡的n種花,從1到n標號。為了在門口展出更多種花,規定第i種花不能超過ai盆,擺花時同一種花放在一起,且不同種類的花需按標號的從小到大的順序依次擺列。試程式設計計算,一共有多少種不同的擺花方案。...