多重背包的二进制分解思想

在背包九讲里面将多重背包转化为01背包,并且进行时间优化,有利用到一个二进制分解的思想。

下面是在网上搜索之后得到的一个关于二进制分解思想的讲解和实现

多重背包二进制分解思想讲解

/**
    在这之前,我空间好像转过一个背包九讲,现在我就只对
    01背包和多重背包有点印象了

    先说下 01 背包,有n 种不同的物品,每个物品有两个属性
    size 体积,value 价值,现在给一个容量为 w 的背包,问
    最多可带走多少价值的物品。

    int f[w+1];   //f[x] 表示背包容量为x 时的最大价值
    for (int i=0; i=size[i]; j++)
            f[j] = max(f[j], f[j-size[i]]+value[i]);

    如果物品不计件数,就是每个物品不只一件的话,稍微改下即可
    for (int i=0; i 0) {
            value[count] = c*v;
            size[count++] = c*s;
        }
    }

    现在用count 代替 n 就和01 背包问题完全一样了

下面是利用上面的讲解,对 HDOJ 2191进行解答,代码如下:

#include 
using namespace std;

int main()
{
	int nCase,Limit,nKind,i,j,k,
		v[111],w[111],c[111],dp[111];
	//v[]存价值,w[]存尺寸,c[]存件数
	//在本题中,价值是米的重量,尺寸是米的价格

	int count,Value[1111],size[1111];
	//count存储分解完后的物品总数
	//Value存储分解完后每件物品的价值
	//size存储分解完后每件物品的尺寸

	cin>>nCase;
	while(nCase--)
	{	
		count=0;
		cin>>Limit>>nKind;
		for(i=0;i>w[i]>>v[i]>>c[i];
			
			//对该种类的c[i]件物品进行二进制分解
			for(j=1;j<=c[i];j<<=1)
			{
				//<<右移1位,相当于乘2
				Value[count]=j*v[i];
				size[count++]=j*w[i];
				c[i] -= j;
			}
			if(c[i] > 0)
			{
				Value[count]=c[i]*v[i];
				size[count++]=c[i]*w[i];
			}
		}

		//经过上面对每一种物品的分解,
		//现在Value[]存的就是分解后的物品价值
		//size[]存的就是分解后的物品尺寸
		//count就相当于原来的n

		//下面就直接用01背包算法来解
		memset(dp,0,sizeof(dp));

		for(i=0;i=size[i];j--)
				if(dp[j] < dp[j-size[i]] + Value[i])
					dp[j]=dp[j-size[i]]+Value[i];
		
		cout<

在背包九讲里面,他的实现方法和这个是不一样的,他是利用01背包和完全背包来配合实现的,下面是那个版本的实现

/*
HDOJ 2191
多重背包用二进制转化的思想,进行优化
*/

#include 
using namespace std;

int weight[110],Value[110],num[110];
int f[1100];
int limit;

inline void ZeroOnePack(int w,int v)
{
	int j;
	for(j=limit;j>=w;j--)
	{
		if(f[j-w]+v > f[j])
			f[j]=f[j-w]+v;
	}
}

inline void CompletePack(int w,int v)
{
	int j;
	for(j=w;j<=limit;j++)
	{
		if(f[j-w]+v > f[j])
			f[j]=f[j-w]+v;
	}
}

inline void MultiplePack(int w,int v,int amount)
{
	if(amount * w >= limit)
	{
		CompletePack(w,v);
		return ;
	}
	for(int k=1;k>T;
	while(T--)
	{
		cin>>limit>>n;
		
		for(int i=0;i>weight[i]>>Value[i]>>num[i];
		
		memset(f,0,sizeof(f));
		
		for(i=0;i


你可能感兴趣的:(Algorithm,c,存储,优化,ini,算法)