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;
}