动态规划背包问题——有依赖的背包

有依赖的背包问题

问题背景:
背包中的物品存在某种依赖关系,比如,你想选择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; 
 } 
 

这是依赖背包的入门题目,他的变式还有很多,当然是不可能用这样枚举的方法过的,以后我有了更优的解法再补充上去。

猜你喜欢

转载自blog.csdn.net/yezi_coder/article/details/103528558