您的位置:首页 > 其它

HDU 3236 Gift Hunting dp 背包

2016-08-05 19:38 274 查看
题意:两个背包,容量分别为v1、v2,有一些为必须装载的物品,然后可以加一个物品而不占背包空间。

背包的变形,dp[i][j][k]表示背包1空间为i,背包2空间为j能容纳最大的价值,k = 0表示还没有拿不占空间的物品,k=0表示拿过了,p表示物品占得空间,传递方向dp[i][j][0]向dp[i][j][1]转移,dp[i-p][j][k]和dp[i][j - p][k]都要向dp[i][j][k]转移。对于必须拿的物品当前状态向下一个状态转移完以后就作废,用负无穷表示。#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int dp[505][55][2];
const int INF = 0x3f3f3f3f;
//int ct[505][55][2];
struct gift{
int p, h, s;
}id[303];
int main() {
int v1, v2, n, i, j, k, ks = 1;
while(~scanf("%d%d%d", &v1, &v2, &n) && (v1 || v2 || n)) {
for(i = 0; i < n; i++) {
scanf("%d%d%d", &id[i].p, &id[i].h, &id[i].s);
}
memset(dp, 0, sizeof(dp));
// memset(ct, 0, sizeof(dp));
for(i = 0; i < n; i++) {
if(id[i].s) {
for(j = v1; j >= 0; j--) {
for(k = v2; k >= 0; k--) {
if(j >= id[i].p && k >= id[i].p) {
dp[j][k][1] = max(dp[j - id[i].p][k][1], dp[j][k - id[i].p][1]) + id[i].h;
dp[j][k][1] = max(dp[j][k][0] + id[i].h, dp[j][k][1]);
dp[j][k][0] = max(dp[j - id[i].p][k][0], dp[j][k - id[i].p][0]) + id[i].h;
}
else if(j >= id[i].p) {
dp[j][k][1] = max(dp[j][k][0], dp[j - id[i].p][k][1]) + id[i].h;
dp[j][k][0] = dp[j - id[i].p][k][0] + id[i].h;
}
else if(k >= id[i].p) {
dp[j][k][1] = max(dp[j][k][0], dp[j][k - id[i].p][1]) + id[i].h;
dp[j][k][0] = dp[j][k- id[i].p][0] + id[i].h;
}
else {
if(dp[j][k][0] < 0)
dp[j][k][1] = -INF;
else dp[j][k][1] = dp[j][k][0] + id[i].h;
dp[j][k][0] = -INF;
}
}
}
}
else for(j = v1; j >= 0; j--) {
for(k = v2; k >= 0; k--) {
if(dp[j][k][1] < dp[j][k][0] + id[i].h)
dp[j][k][1] = dp[j][k][0] + id[i].h;
if(k - id[i].p >= 0) {
if(dp[j][k][0] < dp[j][k - id[i].p][0] + id[i].h) {
dp[j][k][0] = dp[j][k - id[i].p][0] + id[i].h;
}
if(dp[j][k][1] < dp[j][k - id[i].p][1] + id[i].h) {
dp[j][k][1] = dp[j][k - id[i].p][1] + id[i].h;
}
}
if(j - id[i].p >= 0) {
if(dp[j][k][0] < dp[j - id[i].p][k][0] + id[i].h) {
dp[j][k][0] = dp[j - id[i].p][k][0] + id[i].h;
}
if(dp[j][k][1] < dp[j - id[i].p][k][1] + id[i].h) {
dp[j][k][1] = dp[j - id[i].p][k][1] + id[i].h;
}
}
}
}

}
printf("Case %d: ", ks++);
if(dp[v1][v2][1] >= 0) {
printf("%d\n\n", dp[v1][v2][1]);
}
else printf("-1\n\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  HDU dp