P1757 通天之分组背包题解

【题目链接】

洛谷P1757

【解题思路】

和题目名一样,本题就是一道分组背包的模板题,我来讲一下分组背包。
其实就是先将说有的数据按照题意分组,再做01背包即可。

【CODE】

#include<iostream>
using namespace std;
int n,m,maxn;
struct name
{
	int x,y,z;
}a[10100];
name G[1010][1010];//G[i][j]代表第i组的第j个
int num[1010];//num[i]代表第i组的元素个数
int d[10100];//01背包
int main()
{
	cin>>n>>m;
	for (int i=1;i<=m;i++)
	{
		cin>>a[i].x>>a[i].y>>a[i].z;
		//实现一个分组的操作
		num[a[i].z]++;
		G[a[i].z][num[a[i].z]].x=a[i].x;
		G[a[i].z][num[a[i].z]].y=a[i].y;
		maxn=max(a[i].z,maxn);//总组数
	}
	for (int i=1;i<=maxn;i++)//比01多一重第几组的循环
		for (int j=n;j>=0;j--)//每组都只能选一个,如果完全按照01大会多选,所以要将这两重循环反过来
			for (int k=1;k<=num[i];k++)
				if (j>=G[i][k].x)//把判断条件移到这里来
					d[j]=max(d[j],d[j-G[i][k].x]+G[i][k].y);//01背包
	cout<<d[n];
	return 0;
}

【后置知识】

我们所知的所有背包都是可以转化成01背包来做的。
例如:
完全背包

10
2 3 4

我们可以将其转化成

10
2 2 2 2 2 3 3 3 4 4

来做01背包
但是当背包容量很大时,我们会发现这样子的效率太低了。
怎么办呢?
我们可以利用二进制优化。
例如:

100
1

我们拆的时候可以拆成

100
1 2 4 8 16 32 37

这样我们也可以用这 7 7 7 个数,来表示 1 1 1 100 100 100 的所有数,大大提升了01背包的效率。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值