HDU 4501 小明系列故事——買年貨 -- 分組揹包變體

/*
	http://acm.hdu.edu.cn/showproblem.php?pid=4501 小明系列故事——買年貨
	題意:一個現金,一個優惠積分,都可以購買東西,並且只需要其中一個滿足物品的消耗即可購買
	另外可以免費挑選1-5個商品贈送
	求最大的收益價值
	每種物品給出三個消費(現金消耗,積分消耗,免費權消耗),但是這三個消費並不是同時需要滿足,
	所以我們可以將這個問題轉化爲一個分組揹包,每一個物品爲一組,每組最多拿一個
	假設某一個物品的屬性爲 cost_money , point_cost , free_cost , value
	那麼可以將這一組的物品理解爲這三個:
	cost_money value
	point_cost value
	free_cost  value
	這樣就可以用常規的分組揹包來解題了。注意最優狀態的轉移,一個物品不要多算了。

*/

#include <cmath>
#include <string>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define CLR(c,v) (memset(c,v,sizeof(c)))

template <typename _T>
_T Max(_T a,_T b){
	return a<b?b:a;
}
template <typename _T>
_T Max(_T a,_T b,_T c){
	return a<Max(b,c)?Max(b,c):a;
}
template <typename _T>
_T Min(_T a,_T b){
	return a>b?b:a;
}
template <typename _T>
_T Min(_T a,_T b,_T c){
	return a>Min(b,c)?Min(b,c):a;
}

const int inf = -(1<<30);
const int INF =  (1<<30);
const int M   =  1e2 + 5;

int dp[M][M][5+10]; // dp[1.2][cost1][cost2][free]

int main()
{
	//freopen("in.txt","r",stdin);
	int n,max_cost1 , max_cost2 , max_free;
	while(cin >> n >> max_cost1 >> max_cost2 >> max_free){
		CLR(dp,0);
		int free = 1, cost1, cost2, value;
		for(int i = 1 ; i <= n ; i++ ){
			cin >> cost1 >> cost2 >> value;
			for(int j = max_cost1; j >= 0 ; j--)
				for(int k = max_cost2 ; k >= 0 ; k--)
					for(int f = max_free ; f >= 0 ; f--){
						int v1 = (j >=cost1)?(dp[j -cost1][k][f]+value):(0);
						int v2 = (k >=cost2)?(dp[j][k -cost2][f]+value):(0);
						int v3 = (f >=    1)?(dp[j][k][f - 1]   +value):(0);
						dp[j][k][f] = Max(dp[j][k][f] , Max(v1,v2,v3) );
						//if(j>=cost1) // 這裏不能這麼寫。因爲此處的更新會導致一個物品放入了多次
						//	dp[j][k][f] = Max(dp[j][k][f], dp[j-cost1][k][f]+value); 
						//if(k>=cost2)
						//	dp[j][k][f] = Max(dp[j][k][f], dp[j][k-cost2][f]+value);
						//if(f>=free)
						//	dp[j][k][f] = Max(dp[j][k][f], dp[j][k][f-free]+value);
					}
		}
		cout << dp[max_cost1][max_cost2][max_free] << endl;
	}

	return 0;
}

/*
10 10 5 1
3 4 32
3 10 128
4 10 16
1 0 8
5 1 512
10 4 64
8 5 256
4 4 2
10 4 4
4 10 1
 = 1016
*/

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