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;
}
背包的变形,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 1059 Dividing--DP-多重背包问题
- hdu 2602 DP 01背包
- hdu 4276 树形DP + 分组背包
- hdu 1114 Piggy-Bank(DP背包)
- hdu 1114 Piggy-Bank(DP背包)
- hdu 2844 DP 背包
- HDU 3449 Consumer【DP之背包】
- HDU 2159 FATE (动态规划dp之二维完全背包问题)
- HDU 1114 Piggy-Bank (dp问题之完全背包问题)
- HDU1114 Piggy-Bank(完全背包,dp)
- hdu 1171 dp(多重背包)
- HDU 1421 搬寝室 类似背包DP
- hdu 2955(DP背包问题)
- HDU 4276 The Ghost Blows Light [树形背包DP]
- hdu 2955 ( Robberies ) 变相01 背包 DP
- HDU 2546 饭卡 DP(背包)
- hdu 2955(DP背包问题)
- HDU 1011 Starship Troopers 树形DP(0-1背包)
- hdu 2602 Bone Collector 简单dp题 0-1背包
- HDU 1561 树形DP+有依赖的背包