HRBUST 1377 金明的预算方案

题目链接:HRBUST 1377 金明的预算方案

题目大意:
HRBUST 1377 金明的预算方案

题解:
将主件和其附件分为一组,组内包含主件、主件和附件\(1\)、主件和附件\(2\)、主件和附件\(1,2\)至多四个物品。
对所有组进行\(01\)背包,每组只能选一个。

#include <cstring>
#include <iostream>
using namespace std;

int n, m, w[65][4], v[65][4], dp[32010];

int main() {
    while (cin >> n >> m) {
        memset(dp, 0, sizeof(dp));
        memset(w, 0, sizeof(w));
        memset(v, 0, sizeof(v));
        for (int i = 1, a, b, c; i <= m; ++i) {
            cin >> a >> b >> c;
            if (!c) {  // 是主件
                w[i][0] = a * b;
                v[i][0] = a;
            } else {  // 是附件
                if (!w[c][1]) {
                    w[c][1] = a * b;
                    v[c][1] = a;
                } else {
                    w[c][2] = a * b;
                    v[c][2] = a;
                }
            }
        }
        for (int i = 1; i <= m; ++i) {
            for (int j = n; j >= v[i][0]; --j) {
                dp[j] = max(dp[j], dp[j - v[i][0]] + w[i][0]);  // 只买主件
                // 如果没有相应附件则附件值为0,不影响
                if (v[i][0] + v[i][1] + v[i][2] <= j) {  // 买主件和两个附件
                    dp[j] = max(dp[j], dp[j - v[i][1] - v[i][2] - v[i][0]] + w[i][1] + w[i][2] + w[i][0]);
                }
                if (v[i][0] + v[i][1] <= j) {  // 买主件和一种附件
                    dp[j] = max(dp[j], dp[j - v[i][1] - v[i][0]] + w[i][1] + w[i][0]);
                }
                if (v[i][0] + v[i][2] <= j) {  // 买主件和另一种附件
                    dp[j] = max(dp[j], dp[j - v[i][2] - v[i][0]] + w[i][2] + w[i][0]);
                }
            }
        }
        cout << dp[n] << endl;
    }
    return 0;
}
上一篇:最长上升子序列相关问题笔记


下一篇:C++ 常用方法