/*
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
*/
HDU 4501 小明系列故事——买年货 -- 分组揹包变体
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.