回溯法之0-1背包问题

最近在看回溯,感觉就是深度优先遍历,思想差不多,不过对书上的上界函数不是很懂。

自己尝试用回溯写了下背包问题,感觉蛮好。

注释写的很详细了。

上代码。

#include<iostream>
#define Max 100
using namespace std;
//背包问题,尝试用回溯
int x[Max],n,wmax,w[Max],v[Max],cw=0,cv=0;
//cw当前背包重量,cv当前背包价值,x保存每个可行解的物品选择情况
int xmax[Max],maxv=0;//最优值时对应的每个物品的选择情况
void print()
{//打印x数组,测试函数的执行过程
	for(int i=1;i<=n;i++)
		cout<<x[i]<<" ";
	cout<<endl;
}
void copy()
{//将当前状态的最优解的情况保存
	for(int i=1;i<=n;i++)
		xmax[i]=x[i];
}
void fun(int i)
{//回溯,i从1到n
	if(i>n)
	{//到达叶子节点,一个可行解已经出来
//		print();//测试打印
		if(maxv<cv)
		{maxv=cv;copy();}//保存最优解
		return;
	}
	if(cw+w[i]<=wmax)
	{//选择此物品放进背包,进入左子树
		cw+=w[i];
		cv+=v[i];
		x[i]=1;//标记当前第i个货物已放进背包
		fun(i+1);
		cw-=w[i];//回溯到之前的状态准备进入右子树
		cv-=v[i];
		x[i]=0;
	}
	fun(i+1);//不把第i个物品放进背包,进入右子树
}

int main()
{ 
	freopen("data.txt","r",stdin);
    cin>>n>>wmax;  
    for(int i=1;i<=n;i++)  
    {  
        cin>>w[i]>>v[i];  
		x[i]=0;
    }  
	cw=cv=maxv=0;
	fun(1);
	cout<<"最优解的物品选择情况:"<<endl;
	for(i=1;i<=n;i++)
		cout<<xmax[i]<<" ";
	cout<<endl<<"最大价值为:"<<maxv<<endl;
	return 0;
}

数据和程序运行结果:


对于测试函数的打印,传几张,以后再看的话清楚点。

打印的是所有可行解的物品选择情况。


-----2013-12-27 中午14:45   快期末了,下周去抱佛脚,最近几天还是按计划进行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值