算法知识点: DP,分组背包问题
复杂度:
解题思路:
可以将每个主件及其附件看作一个物品组,记主件为 ,两个附件为,则最多一共有4种组合:
这四种组合是互斥的,最多只能从中选一种,因此可以将每种组合看作一个物品,那么问题就变成了分组背包问题。
C++ 代码:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> using namespace std; typedef pair <int, int> PII; const int N = 70, M = 32010; int m, n; PII a[N]; vector<PII> b[N]; int f[M]; int main() { scanf("%d%d", &m, &n); for (int i = 1; i <= n; i++) { int v, w, p; scanf("%d%d%d", &v, &w, &p); w *= v; if (!p) a[i] = { v, w }; else b[p].push_back( { v, w }); } for (int i = 1; i <= n; i++) { if (!a[i].first) continue; for (int j = m; j >= 0; j--) for (int k = 0; k < 1 << b[i].size(); k++) { int v = a[i].first, w = a[i].second; for (int u = 0; u < b[i].size(); u++) if (k >> u &1) { v += b[i][u].first; w += b[i][u].second; } if (j >= v) f[j] = max(f[j], f[j - v] + w); } } printf("%d\n", f[m]); return 0; }