P1064 金明的预算方案 暴力DP 背包
据传这类问题叫做有依赖性的背包问题:
选某个物品的同时必须连带选其他物品
容易想到其实是决策发生了变化:
可以选啥都不选
可以只选主件
可以选主件+一个附件
可以选主件+两个附件
其他和01背包一样
struct Bag { int w; int val; Bag(int x = 0,int y = 0) : w(x),val(y){} }; vector<Bag> a[65]; Bag s[65]; int vis[65]; int dp[32005]; int main() { int n, m; int x, y, z; n = readint(), m = readint(); for (int i = 0; i < m; i++) { x = readint(), y = readint(), z = readint(); if (!z) s[i].val = y, s[i].w = x; else a[z - 1].push_back(Bag(x, y)), vis[i] = -1; } for (int i = 0; i < m; i++) { if (vis[i] == -1) continue; for (int j = n; j >= s[i].w; j--) { int res = dp[j]; res = max(res, dp[j - s[i].w] + s[i].val * s[i].w); if (!a[i].empty()) { if (j - s[i].w - a[i][0].w >= 0) res = max(res, dp[j - s[i].w - a[i][0].w] + s[i].val * s[i].w + a[i][0].val * a[i][0].w); if (a[i].size() > 1) { if (j - s[i].w - a[i][1].w >= 0) res = max(res, dp[j - s[i].w - a[i][1].w] + a[i][1].val * a[i][1].w + s[i].val * s[i].w); if (j - s[i].w - a[i][0].w - a[i][1].w >= 0) res = max(res, dp[j - s[i].w - a[i][0].w - a[i][1].w] + s[i].val*s[i].w + a[i][0].val * a[i][0].w+ a[i][1].w * a[i][1].val); } } dp[j] = res; } } Put(dp[n]); }