4. 多重背包问题 I

Posted 幽殇默

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了4. 多重背包问题 I相关的知识,希望对你有一定的参考价值。

在这里插入图片描述
https://www.acwing.com/problem/content/4/

朴素做法:
状态转移方程:f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+k*w[i]);

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e3+10;
int f[N][N],v[N],w[N],s[N],n,m;
int main(void)
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>v[i]>>w[i]>>s[i];
	
	for(int i=1;i<=n;i++)
	{
		for(int j=0;j<=m;j++)
		{
			for(int k=0;k<=s[i]&&k*v[i]<=j;k++)
			{
				f[i][j]=max(f[i][j],f[i-1][j-v[i]*k]+k*w[i]);
			}
		}
	}
	cout<<f[n][m]<<endl;
	return 0;
}

在这里插入图片描述
https://www.acwing.com/problem/content/5/

多重背包的本质其实就是一个01背包
二进制优化:

假设: A物品有7个,B物品有3个。 
a1,a2,a3,a4,a5,a6,a7,b1,b2,b3.  
对于每一个我们都有 选和不选两种选择,一共10个物品,枚举的次数:2^10。 
a1,(a2,a3),(a4,a5,a6,a7),(b1),(b2,b3);
对于每一个我们都有 选和不选两种选择,一共5个物品枚举的次数:2^5. 

1代表选,0 代表不选 
此时 
1000000,000   等价于 100,00 
0110000,000   等价于 010,00
....... 
我们每一种的情况都可以用二进制优化的方式组合出来。
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5*2+5000;
int f[N],v[N],w[N],cnt,n,m;
int main(void)
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int a,b,s;
		cin>>a>>b>>s;
		int k=1;
		while(k<=s)
		{
			cnt++;
			v[cnt]=a*k;
			w[cnt]=b*k;
			s-=k;
			k=k*2;
		}
		if(s>0)
		{
			cnt++;
			v[cnt]=a*s;
			w[cnt]=b*s; 
		}
	}
	
	n=cnt;
	for(int i=1;i<=n;i++)
	{
		for(int j=m;j>=v[i];j--)
		f[j]=max(f[j],f[j-v[i]]+w[i]);
	}
	cout<<f[m]<<endl;
	return 0;
}

以上是关于4. 多重背包问题 I的主要内容,如果未能解决你的问题,请参考以下文章

多重背包问题(二进制优化)

背包问题

蒟蒻吃药计划-治疗系列 #round4 多重背包+混合背包代码存放

01背包+完全背包+多重背包+单调队列

多重背包

背包问题