码迷,mamicode.com
首页 > 其他好文 > 详细

回溯法解决0/1背包问题

时间:2021-05-03 12:34:47      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:oid   return   end   选择   val   sid   背包   std   value   

思路
采用暴力搜索,然后进行剪枝

每一次递归先判断是否考虑完所有物品
分两种情况递归
1.考虑把当前物品装入背包
1.当前背包可以装的下这个物品
背包容量减去这个物品的重量
总价值加上这个比尔堡的重量
数组标记征额背包已经访问过
搜索下一个背包情况
还原标记情况
2.当前背包不可装下这个物品
考虑下一个背包情况
2.考虑下一个背包情况

#include<iostream>
using namespace std;
const int N = 100010; 
int capacity;	//背包容量 
bool select[N];	//当前方案选择 
bool optimal[N];	//最佳方案 
int maxtotalvalue = 0;	//最大价值
int valueofpackge = 0;	//当前背包价值
int residualcapacity;	//剩余背包价值
int n;		//背包个数 
int weight[N];	//背包重量 
int value[N]; 	//背包价格
void dfs(int i)
{
	//考虑完一种背包选择方案 
	if(i > n)
	{
		if(valueofpackge >= maxtotalvalue)//当前方案比记录的最优方案更好
		{
			for(int i = 1; i <= n; i ++ ) optimal[i] = select[i];
			maxtotalvalue = valueofpackge;
		 } 
	 } 
	 else
	 //遍历左子树(选中当前背包) 
	 {
		 residualcapacity -= weight[i];//先装进去判断符号,符号为正装得下,负装不下
		 if(residualcapacity >= 0)//当前背包空间够装这个物品 
		 {
		 	//背包装入当前物品 
		 	select[i] = 1;
		 	valueofpackge += value[i];
		 	dfs(i + 1);
		 	//还原
			select[i] = 0;
			valueofpackge -= value[i];
			residualcapacity +=  weight[i];
		  }
		  else  // 当前空间不够装这个物品 
		  {
		  	residualcapacity += weight[i];//容量不够,把物品放回去
		}		  
	}
	//遍历右子树(不选中当前背包直接看下一个背包) 
	dfs(i + 1);
}
int main()
{
	cin >> n;
	for(int i = 1; i <= n; i ++ )
	{
		cin >> weight[i] >> value[i];//重量和价值 
		capacity += value[i];
	}
	residualcapacity = capacity;
	dfs(1);
	cout << "背包最大价值为:" << maxtotalvalue << endl;
	return 0; 
} 

回溯法解决0/1背包问题

标签:oid   return   end   选择   val   sid   背包   std   value   

原文地址:https://www.cnblogs.com/jw-zhao/p/14723966.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!