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