0-1背包

0-1背包问题的回朔法实现

设有0-1背包问题,p1,2...n)价值,w1,2...n) 重,c背包容量。

利用深度优先搜索,构造解空间树。每一个物品有1(取),0(不取),分别对应解空间树的左右子树。故解空间树为n+1深的完全二叉树。每个节点表示当前总价值。

 

算法实现:以类的方式,以减少参数的传递。n(物品数),bestp最大价值,cp 当前价值。

#include <iostream>

#include <stdio.h>

using namespace std;

 

class knapack

{

friend int knap();

public:

 

int n;//物品数量

int *p;//物品价值

int *w;//物品重量

int c;//背包容量

int bestp;

int cp;

int cw;//当前重量

int *bestl;//最优路径

int *cl;//当前路径

public:

void backtrack(int i);

int bound(int i);//计算上界,若上界小于bestp,剪枝

};

 

void knapack:: backtrack(int i)//i深度

{

if(i>n)

{

bestp=cp;

bestl=cl;

return;

}

if(cw+w[i]<=c)

{

//进入左子树

cw+=w[i];

cl[i]=1;

cp+=p[i];

backtrack(i+1);

cw-=w[i];

cl[i]=0;

cp-=p[i];

}

if(bound(i+1)>bestp)

{

//进入又子树

backtrack(i+1);

}

}

 

int  knapack::bound(int i)

{

//计算上界

int b=cp;

int leflc=c-cw;

for(int j=i;i<=n && w[i] <leflc;i++)

{

b+=p[i];

leflc-=w[i];

}

if (i<=n)

b+=p[i]*leflc/w[i];

return b;

 

int knap(int n,int w[],int p[],int c)

{

class knapack a;

a.n=n;

a.c=c;

a.p=p;

a.w=w;

a.bestl=new int [n];

a.cl=new int [n];

a.bestp=0;

a.cp=0;

a.cw=0;

a.backtrack(1);

return a.bestp;

 

}

 

int main(int argc, char const *argv[])

{

int n;

cin>>n;

int *p=new int [n+1];

int *w=new int [n+1];

for (int i = 1; i <= n; ++i)

{

cin>>w[i];

}

for (int i = 1; i <= n; ++i)

{

cin>>p[i];

}

int c;

cin>>c;

printf("%d\n",knap(n,w,p,c));

return 0;

}

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值