HDU 3236 Gift Hunting dp 背包

来源:互联网 发布:抗衰老精华 知乎 编辑:程序博客网 时间:2024/05/20 07:34

题意:两个背包,容量分别为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;}

0 0
原创粉丝点击