多重背包二进制优化

因为一直没有搞明白多重背包二进制优化的原理,故作此文

问题描述

\(N\) 种物品和一个容量是 \(V\) 的背包。
\(i\) 种物品最多有 \(s_i\) 件,每件体积是 \(v_i\),价值是 \(w_i\)
求解将哪些物品装入背包,可使物品体积总和不超过背包容量,且价值总和最大。

求法:

朴素求法

把多重背包转变为01背包求解

优化求法

二进制优化

什么是二进制优化

代码(二进制优化版)

#include<bits/stdc++.h>

using namespace std;

int n,w;
int va[100010],we[100010];
int f[100010];

inline int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') f=-1; 
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=x*10+ch-'0';
		ch=getchar();
	}
	return x*f;
}

int main()
{
	n=read();w=read();
	int num=0;
	for(int i=1;i<=n;i++)
	{
		int val,wei,m;
		val=read();
		wei=read();
		m=read();
		for(int j=1;j<=m;j<<=1)
		{
			num++;
			va[num]=j*val;
			we[num]=j*wei;
			m-=j;
		}
		if(m){
			num++;
			va[num]=m*val;
			we[num]=m*wei;
		}
	}
	for(int i=1;i<=num;i++)
	{
		for(int j=w;j>=we[i];j--)
		{
			f[j]=max(f[j],f[j-we[i]]+va[i]);
		}
	}
	printf("%d\n",f[w]);
	return 0;
 } 

posted @ 2025-02-10 17:19  lazy_ZJY  阅读(71)  评论(0)    收藏  举报