装满01背包问题和01背包问题

本文详细介绍了01背包问题的解决方法,包括状态转移方程的推导过程、不同应用场景下的算法实现,以及如何通过代码实现来寻找最优解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   01背包是在M件物品取出若干件放在空间为W的背包里,每件物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解将那些物品装入背包可使总价值最大。

    1) 子问题定义:F[i][j]表示前i件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值。

    2) 根据第i件物品放或不放进行决策

                                 

    其中F[i-1][j]表示前i-1件物品中选取若干件物品放入剩余空间为j的背包中所能得到的最大价值;

    而F[i-1][j-C[i]]+W[i]表示前i-1件物品中选取若干件物品放入剩余空间为j-C[i]的背包中所能取得的最大价值加上第i件物品的价值。

    根据第i件物品放或是不放确定遍历到第i件物品时的状态F[i][j]。

    设物品件数为N,背包容量为V,第i件物品体积为C[i],第i件物品价值为W[i]。转载于http://blog.youkuaiyun.com/wumuzi520/article/details/7014830

 01装满背包

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int nLen, int capacity)
{
	int * a= new int [capacity+1];
	memset(a,0,(capacity+1)*sizeof(int));
	a[0] = 1;
	for(int i = 0; i < nLen; i++)
	{
		for(int j = nCapacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
		{
			if(j >= Weight[i])
				a[j] += a[j-Weight[i]];
		}
	}

	int k = a[capacity];
	delete [] a;
	return k;
}
01背包问题
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int Len, int capacity,int value[])
{
	int * a= new int [capacity+1];
	memset(a,0,(capacity+1)*sizeof(int));
	for(int i = 1; i < Len; i++)
	{
		for(int j = Capacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
		{
				a[j]=max(a[j],a[j-Weight[i]]+value[i]);
		}
	}

	int k = a[capacity];
	delete [] a;
	return k;
}
打印构成最大背包的物品

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int facs(int Weight[], int nLen, int capacity,int value[])
{
	int * a= new int [capacity+1];
	int Path[100][100];
	memset(a,0,(capacity+1)*sizeof(int));
	for(int i = 1; i < Len; i++)
	{  
	     Path[i][j] = 0;
		for(int j = nCapacity; j >=Weight[i]; j--)//为什么这里要逆序,其实我们这里是改进的代码因为我们要保证a[j]是i-1时刻的值
		{
				a[j]=max(a[j],a[j-Weight[i]]+value[i]);
				 Path[i][j] = 1;
		}
	}
	 int i = Len, j = capacity;  
    while(i > 0 && j > 0)  
    {  
        if(Path[i][j] == 1)  
        {  
            cout << Weight[i-1] << " ";  
            j -= Weight[i-1];  
        }  
        i--;  
    }  

}

完全背包问题下方是转满这个背包有几种方案

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<map>
#include<string>
#define INF 0x7fffffff
using namespace std;
int Package02_FullOfPackage_Compress(int Weight[], int nLen, int nCapacity)
{
	int * MethodTable = new int [nCapacity+1];
	memset(MethodTable,0,(nCapacity+1)*sizeof(int));
	MethodTable[0] = 1;
	for(int i = 0; i < nLen; i++)
	{
		for(int j = Weight[i]; j <= nCapacity; j++)
		{
			if(j >= Weight[i])
				MethodTable[j] += MethodTable[j-Weight[i]];
		}
	}
	int nRet = MethodTable[nCapacity];
	delete [] MethodTable;
	return nRet;
}
int main()
{
    int Weight[] = {5,10};
    int nCapacity = 20;
    cout << "AllCount:" << Package02_FullOfPackage_Compress(Weight,2,nCapacity) << endl;
    return 0;
}
完全背包是在N种物品中选取若干件(同一种物品可多次选取)放在空间为V的背包里,每种物品的体积为C1,C2,…,Cn,与之相对应的价值为W1,W2,…,Wn.求解怎么装物品可使背包里物品总价值最大。

int Package02_Compress(int Weight[], int Value[], int nLen, int nCapacity)
{
	int * Table = new int [nCapacity+1];
	memset(Table,0,(nCapacity+1)*sizeof(int));
	for(int i = 0; i < nLen; i++)
	{
		for(int j = Weight[i]; j <=nCapacity; j++)
		{
			if(Table[j] < Table[j-Weight[i]]+Value[i])
			{
				Table[j] = Table[j-Weight[i]]+Value[i];
			}
		}	
	}
	int nRet = Table[nCapacity];	
	delete [] Table;
	return nRet;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值