在背包问题中,对于物品的选择只有两种,装进去或者选择不装进去。
于是可以运用二叉树中有两个子节点的特性
左子树表示将该物品装进背包(若此时背包容量小于物品重量则不装)
右子树代表不装入该物品
最后遍历二叉树,找出权值(装入物品总价值)最大的节点
将二叉树节点定义为这样式的
将每个物品的价值与重量也用一个结构体装起来(方便)
以下为所有代码
#include <iostream>
using namespace std;
typedef struct thing{
int weight;
int value;
}dx;
typedef struct node{
int allin; //该节点装入背包的物品总价值
struct node *right,*lift;
}BTnode;
int reamax=0;
BTnode* creattree(dx th[]/*物品*/,int max/*背包最大容量*/,int n/*第几个物品*/,
int v/*背包现在装入的总价值*/,bool k/*是否将该物品装入*/,int flag/*是否是第一个无意义空节点*/)
{
BTnode *p;
if(n==0||max==0)//如果装到最后一个物品或者背包没有容量了就结束
{
p=NULL;
}
else
{
p=new BTnode;
p->allin=0;
if(flag!=0)
{
if(k==1&&max>th[n-1].weight)
{
p->allin=th[n-1].value+v;
max-=th[n-1].weight;
}
else
{
p->allin=v;
}
}
p->lift=creattree(th,max,n-1,p->allin,1,1);
p->right=creattree(th,max,n-1,p->allin,0,1);
}
return p;
}
void midmax(BTnode *p)
{
if(p!=NULL)
{
if(p->lift==NULL&&p->right==NULL&&p->allin>reamax){
reamax=p->allin;
}
midmax(p->lift);
midmax(p->right);
}
}
int main()
{
int n,max_size;
BTnode *root;
cout<<"请输入物品的个数:"<<endl;
cin>>n;
cout<<"请输入每个物品的质量与价值:"<<endl;
dx th[n+1];
for(int i=1;i<=n;i++)
{
cin>>th[i].weight>>th[i].value;
}
cout<<"请输入背包的最大容量:"<<endl;
cin>>max_size;
root=creattree(th,max_size,n+1,0,1,0);
midmax(root);
cout<<"背包最大容量为:"<<reamax<<endl;
return 0;
}
算法复杂度o(2^n)