多重背包合集

AcWing 4. 多重背包问题 I O(n^3)

#include<bits/stdc++.h>
using namespace std;
const int N = 110;
int n,m;
int f[N];
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int v,w,s;
		cin>>v>>w>>s;
		for(int j=m;j>=0;j--)
		for(int k=1;k<=s && k*v<=j;k++)
		f[j]=max(f[j],f[j-k*v]+k*w);
		
		
	}
	cout<<f[m];
	return 0;
} 

AcWing 5. 多重背包问题 II 当N,M,K都是上千的话,我们需要优化(二进制优化)

多重背包---->01背包,第i个物品有s个,我们就把它拆成s份放到物品组中去,直接拆的话数量也是多,也会TLE

二进制的拆法:

0~7:1 2 4的选法,即log2(x)上取整

如果是0~10的话,不能直接用1 2 4 8,因为这样可以枚举到0~15的所有数,所以我们需要对最后一个数进行减操作

即 1 2 4 3 ,物品x份,直接变成log(x)份 这道题复杂度:1000 * 11 * 2000 = 2*10^7

#include<bits/stdc++.h>
using namespace std;
const int N = 2020; 
int n,m,f[N];
struct Goods
{
	int v,w;
};
int main()
{
	vector<Goods> goods;
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int v,w,s;
		cin>>v>>w>>s;
		for(int k=1;k<=s;k*=2)
		{
			s-=k;
			goods.push_back({v*k,w*k});
		}
		if(s>0) goods.push_back({v*s,w*s});
	}
	
	for(auto good:goods)
		for(int j=m;j>=good.v;j--)
		   f[j]=max(f[j],f[j-good.v]+good.w);
	cout<<f[m];	   
	return 0;
}

AcWing 6. 多重背包问题 III

数据范围

0<N≤10000<N≤1000
0<V≤200000<V≤20000
0<vi,wi,si≤20000

这个时候就需用单调队列进行优化

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值