第九章 動態規劃-1299:糖果

1299:糖果

時間限制: 1000 ms 內存限制: 65536 KB
提交數: 3077 通過數: 1293
【題目描述】
由於在維護世界和平的事務中做出巨大貢獻,Dzx被贈予糖果公司2010年5月23日當天無限量糖果免費優惠券。在這一天,Dzx可以從糖果公司的N件產品中任意選擇若干件帶回家享用。糖果公司的N件產品每件都包含數量不同的糖果。Dzx希望他選擇的產品包含的糖果總數是K的整數倍,這樣他才能平均地將糖果分給幫助他維護世界和平的夥伴們。當然,在滿足這一條件的基礎上,糖果總數越多越好。Dzx最多能帶走多少糖果呢?

注意:Dzx只能將糖果公司的產品整件帶走。

【輸入】
第一行包含兩個整數N(1≤N≤100)和K(1≤K≤100)。

以下N行每行1個整數,表示糖果公司該件產品中包含的糖果數目,不超過1000000。

【輸出】
符合要求的最多能達到的糖果總數,如果不能達到K的倍數這一要求,輸出0。

【輸入樣例】
5 7
1
2
3
4
5
【輸出樣例】
14
【提示】
Dzx的選擇是2+3+4+5=14,這樣糖果總數是7的倍數,並且是總數最多的選擇。


思路:狀態轉移方程:f[i][j]=max(f[i][j],max(f[i-1][j],f[i-1][(k+j-a[i]%k)%k]+a[i]));
f[i][j]表是,前i個物品,%k是j的最大糖果數目
1.不取第i個包,那就是 f[i-1][j],
2.取第i個包,那麼就要判斷能轉移到f[i][j]的前一種狀態, f[i-1][(k+j-a[i]%k)%k],
假設 f[i][j]是由f[i-1][d]轉移過來的,那麼j=(d+a[i]%k)%k, 根據這個公式,可以得出d是(k+j-a[i]%k)%k,()里加一個k,是爲了防止 j-a[i]%k<0。
f[0][0]=0;注意這裏區別好糖果是0,就是沒取包,可以達到餘數是0,而取包之後達不到的狀態賦值爲-INF,防止出現某個糖果數,是由不成立的狀態轉移來的。
f[1][0]=0; f[1][a[1]%k]=a[1]; 最後輸出;f[n][0] .

#include<cstdio>
#include<iostream>
#include<algorithm>
#define INF 0X3f3f3f3f
using namespace std;
const int N = 1005;
int n,k,a[N],f[N][N];
int main(){
	cin >> n >> k;
	for(int i = 1; i <= n; i++)
	cin >> a[i];
	for(int i = 1; i < k; i++)
	f[0][i] = -INF;
	for(int i = 1; i <= n; i++)
	  for(int j = k-1; j >= 0 ; j--)
	  f[i][j] = max(f[i-1][j],f[i-1][(j-a[i]%k+k)%k] + a[i]);
	  cout << f[n][0] <<endl;
	  return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章