hdu4501 三维01背包,三个条件

来源:互联网 发布:永久免费域名申请 编辑:程序博客网 时间:2024/05/16 12:17

题目链接:点击打开链接


题意:

中文题,不在详述;


理解:

三维01背包;

递推式含义:dp[j][k][l] 表示用 j 的钱和 k 的积分 和 l 的免费次数能买到最大的价值;

递推式:dp[j][k][l] = max(dp[j][k][l], dp[j - a[i]][k][l] + w[i], dp[j][k - b[i]][l] + w[i], dp[j][k][l - 1] + w[i]);

其中的值根据代码定义;

注意的是和01背包不同的是在简化以后需要足以有的值是可以为 0 的;

即:j == 0 || k == 0 || l == 0;


代码如下:


#include <cstdio>#include <cstdlib>#include <cstring>#include <cmath>#include <ctime>#include <iostream>#include <algorithm>#include <vector>#include <string>#include <map>#include <set>#include <queue>#include <stack>using namespace std;typedef long long LL;typedef pair<int, int> PII;const int MIN_INF = 1e-7;const int MAX_INF = (1e9) + 7;#define X first#define Y secondint dp[105][105][10];int a[105], b[105], w[105];int main() {    int n, v1, v2, f;    while (cin >> n >> v1 >> v2 >> f) {        for (int i = 1; i <= n; ++i) {            cin >> a[i] >> b[i] >> w[i];        }        memset(dp, 0, sizeof(dp));        for (int i = 1; i <= n; ++i) {            for (int j = v1; j >= 0; --j) {                for (int k = v2; k >= 0; --k) {                    for (int l = f; l >= 0; --l) { //其中j、k、l都可以为0,而在简化的 01 背包中是不用算到零的;                        int tp = 0;                        if (j >= a[i]) {                            tp = max(dp[j - a[i]][k][l] + w[i], tp);                        }                        if (k >= b[i]) {                            tp = max(dp[j][k - b[i]][l] + w[i], tp);                        }                        if (l >= 1) {                            tp = max(dp[j][k][l - 1] + w[i], tp);                        }                        dp[j][k][l] = max(dp[j][k][l], tp);                    }                }            }        }        cout << dp[v1][v2][f] << endl;    }    return 0;}


0 0