有依赖的背包问题
问题背景:
背包中的物品存在某种依赖关系,比如,你想选择i物品,就必须选择物品j。可能还有多重依赖的关系。这种问题的鼻祖应该是2006NOIP的金明的预算方案,我就以这道题来讲述一下我如今会的比较笨的方法:
由于复制的格式问题,我在这里贴上洛谷上这题的连接:
洛谷金明的预算方案
乍一看这题好难,毫无头绪,但是把问题想清楚之后,就感觉也不是那么难。因为在这里附件最多两个,我们是可以进行枚举的:
对于每一个物品族(把主件和附件称为一个物品族)
① 买主件不要附件
② 买主件和附件1不要附件2
③ 买主件和附件2不要附件1
④ 买主件和所有附件
⑤ 主件都不买
想清楚这个之后,就是01背包的问题了
贴上AC代码:
#include<iostream>
#include<algorithm>
using namespace std;
int mc[20010], mv[20010], fc[200][3], fv[200][3], f[40010];
//mc是主件的价格 mv是主件的价值 fc是附件的价格 fv是附件的价值
int n, m, v, p, q;
int main()
{
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
cin >> v >> p >> q;
if(q == 0)
{
mc[i] = v;
mv[i] = p * v;
}
if(q > 0)
if(fc[q][1] > 0)
{
fc[q][2] = v;
fv[q][2] = v * p;
}
else
{
fc[q][1] = v;
fv[q][1] = v * p;
}
}
for(int i = 1; i <= m; i++)
for(int j = n; j >= mc[i]; j--)
{
//买主件
f[j] = max(f[j], f[j - mc[i]] + mv[i]);
//买主件和附件1
if(j >= mc[i] + fc[i][1])
f[j] = max(f[j], f[j - mc[i] - fc[i][1]] + mv[i] + fv[i][1]);
//买主件和附件2
if(j >= mc[i] + fc[i][2])
f[j] = max(f[j], f[j - mc[i] - fc[i][2]] + mv[i] + fv[i][2]);
//都买
if(j >= mc[i] + fc[i][1] + fc[i][2])
f[j] = max(f[j], f[j - mc[i] - fc[i][1] - fc[i][2]] + mv[i] + fv[i][1] + fv[i][2]);
}
cout << f[n];
return 0;
}
这是依赖背包的入门题目,他的变式还有很多,当然是不可能用这样枚举的方法过的,以后我有了更优的解法再补充上去。