有依赖的背包问题 ->主件最后放,放主件时才更新最终背包

目录

练习题:

这种题直接当附件有无数多个做吧

思路:

AC代码:


练习题:

P1064 [NOIP2006 提高组] 金明的预算方案 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

这种题直接当附件有无数多个做吧

思路:

即标题 : 主件最后放,放主件时才更新最终背包

细节:

1.有主件与附件,买附件一定要买主件。(计算价值时,是物件的价格*重要度

2.说最终背包,说明我们还有个背包,即临时背包。

我们令最终背包为fdp,临时背包为dp。

3.我们每次处理一组,一组指的是一个主件及其所有附件。

临时背包dp就对附件做计算(即01背包的计算),然后最后对主件计算时(也是背包)才往最终背包fdp里放。

4.所以我开局分了组。

主件是第几个就放到第几个vector<vector<int>>里,他的附件都放主件一个vector<int>里

每次处理一个vector<int>,里面放的是主件和他的附件的编号(因为此题是这样的编号),然后倒着来(但主件也未必是他们之中第一个出现,所以最后再处理主件吧)

AC代码:

每次记得用最终背包fdp清理临时背包dp

const int MAX = 1e5;

int v[MAX], p[MAX], q[MAX];
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	int n, m;
	cin >> n >> m;
	vector<vector<int>>arr(m + 1);
	for (int i = 1; i <= m; i++)
	{
		cin >> v[i] >> p[i] >> q[i];
		if (q[i] != 0)//0说明本身主件,不是0就去找自己的主件数组,就完成了分组
		{
			arr[q[i]].push_back(i);
		}
		else
		{
			arr[i].push_back(i);
		}
	}



	int dp[MAX] = { 0 }, fdp[MAX] = { 0 };
	for (int i = 1; i <= m; i++)
	{
		for (int k = arr[i].size() - 1;k>=0;k--)//附件的01背包找最大价值
		{
			int x = arr[i][k];
			if (x != i)
				for (int j = n - v[arr[i][0]]/*留位子*/; j >= v[x]; j-=1)
				{
					dp[j] = max(dp[j], dp[j - v[x]] + v[x]*p[x]);
				}
		}

		if(arr[i].size()>0)
		for (int j = n; j >= v[i]; j -= 1)//买到主件才算数
		{
			fdp[j] = max(fdp[j], dp[j - v[i]] + v[i] * p[i]);
		}
		memcpy(dp, fdp, sizeof fdp);
	}
	cout << fdp[n];
	return 0;
}

  • 22
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值