背包问题-回溯法

0-1背包:给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得在总重量不超过背包的容量C的前提下装入背包中物品的总价值最大。

#include<iostream>
using namespace std;

class Bag
{ private:
	int c;         //背包容量
	int n;        //物品数量
	int *w;       //各物品重量
	int *p;       //各物品价值
	int *x;       //解向量
	int cw;      //当前重量
	int cv;      //当前价值
	int bestv;  //当前最优价值
	int *bestx;  //当前最优价值对应的解
public: 
	Bag();
	~Bag();
	void Output();
	void Set(int n);
	void Input();
	void Backtrack(int t);
};

Bag::Bag()
{  n=0; 
   cw=cv=bestv=0;
   w=p=x=bestx=NULL;
}

Bag::~Bag()
{
	delete x;
	delete p;
	delete w;
	delete bestx;
}

void Bag::Set(int n)
{
	this->n=n;
	x=new int[n];
	p=new int[n];
	w=new int[n];
	bestx=new int[n];
}

void Bag::Input()
{
	int i;
	cout<<"请输入背包容量:"<<endl;
	cin>>c;
	cout<<"请输入各物品重量:"<<endl;
	for (i=0; i<n; i++)
		cin>>w[i];
    cout<<"请输入各物品价值:"<<endl;
	for (i=0; i<n; i++)
		cin>>p[i];
}

void Bag::Output()
{
	int i;
	for (i=0;i<n; i++)
		cout<<bestx[i]<<"  ";
	cout<<endl;
}

void Bag::Backtrack(int t)
{
   if (t>n-1)
   {
	   if (cv>bestv)
	   {
		   bestv=cv;
		   for (int i=0; i<n; i++)
			   bestx[i]=x[i];
	   }
   }
   else
   {
	   for (int i=0; i<=1; i++)
	   { 
		   x[t]=i;
	       if (i==0)
		      Backtrack(t+1);
	       else
	         if(cw+w[t]<=c)
			 {
			   cw=cw+w[t];
			   cv=cv+p[t];
			   Backtrack(t+1);
			   cw=cw-w[t];
			   cv=cv-p[t];
			 }
	   }
   }
}

int main()
{
	Bag M;
	int n;
	cout<<"请输入物品的数量";
	cin>>n;
	M.Set(n);
	M.Input();
	M.Backtrack(0);
	M.Output();
	return 0;

}

解法二:

#include<iostream>
using namespace std;

class Bag
{ private:
	int c;         //背包容量
	int n;        //物品数量
	int *w;       //各物品重量
	int *p;       //各物品价值
	int *x;       //解向量
	int cw;      //当前重量
	int cv;      //当前价值
	int bestv;  //当前最优价值
	int *bestx;  //当前最优价值对应的解
	int r;       //当前剩余物品的价值总和
public: 
	Bag();
	~Bag();
	void Output();
	void Set(int n);
	void Input();
	void Backtrack(int t);
};

Bag::Bag()
{  n=0; 
   cw=cv=bestv=0;
   w=p=x=bestx=NULL;
}

Bag::~Bag()
{
	delete x;
	delete p;
	delete w;
	delete bestx;
}

void Bag::Set(int n)
{
	this->n=n;
	x=new int[n];
	p=new int[n];
	w=new int[n];
	bestx=new int[n];
}

void Bag::Input()
{
	int i;
	cout<<"请输入背包容量:"<<endl;
	cin>>c;
	cout<<"请输入各物品重量:"<<endl;
	for (i=0; i<n; i++)
		cin>>w[i];
	r=0;
    cout<<"请输入各物品价值:"<<endl;
	for (i=0; i<n; i++)
	{
		cin>>p[i];
		r=r+p[i];
	}
}

void Bag::Output()
{
	int i;
	for (i=0;i<n; i++)
		cout<<bestx[i]<<"  ";
	cout<<endl;
}

void Bag::Backtrack(int t)
{
   if (t>n-1)
   {
	   if (cv>bestv)
	   {
		   bestv=cv;
		   for (int i=0; i<n; i++)
			   bestx[i]=x[i];
	   }
   }
   else
   {
	   for (int i=0; i<=1; i++)
	   { 
		   x[t]=i;
	       if (i==0 && cv+r>bestv)
		      Backtrack(t+1);
	       else
	         if(cw+w[t]<=c)
			 { r=r-p[t];
			   cw=cw+w[t];
			   cv=cv+p[t];
			   Backtrack(t+1);
			   cw=cw-w[t];
			   cv=cv-p[t];
			   r=r+p[t];
			 }
	   }
   }
}

int main()
{
	Bag M;
	int n;
	cout<<"请输入物品的数量";
	cin>>n;
	M.Set(n);
	M.Input();
	M.Backtrack(0);
	M.Output();
	return 0;

}

 

    原文作者:回溯法
    原文地址: https://blog.csdn.net/xu_benjamin/article/details/85331804
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞