01背包回溯法复杂度_【求助】0-1背包问题回溯法实现

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

我用w[5]={2,2,6,5,4},p[5]={6,3,5,4,6}进行验证,最优值应该是15,可是输出结果是14

#include

#include

using namespace std;

class Knap

{

friend int Knaspack(int *,int *,int ,int );

public :

int Bound(int i);

void Backtrack(int i);

int c;//背包承载物品的数量

int n;//物品数

int *w;//物品重量数组

int *p;//物品价值数组

int cw;//当前重量

int cp;//当前价值

int bestp;//当前最有价值

};

void Knap::Backtrack(int i)

{

if(i>n)//到达叶子结点

{

bestp=cp;

return ;

}

if(cw+w[i]<=c)//搜素左子树

{

cw+=w[i];

cp+=p[i];

Backtrack(i+1);

cw-=w[i];

cp-=p[i];

}

if(Bound(i+1)>bestp)//搜索右子树

Backtrack(i+1);

}

int Knap::Bound(int i)//计算上界

{

int cleft=c-cw;//剩余容量

int b=cp;

//以物品单位重量价值递减序装入物品

while(i<=n&&w[i]<=cleft)

{

cleft-=w[i];

b+=p[i];

i++;

}

//装满物品

if(i<=n)

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

return b;

}

class Object

{

friend int Knaspack(int *,int *,int ,int );

public:

int operator<=(Object a)const

{

return (d>=a.d);

}

int ID;///物品编号

float d;//单位物品重量价值

};

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

{//初始化

int W=0;

int P=0;

Object * Q=new Object[n];

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

{

Q[i-1].ID=i;

Q[i-1].d=1.0*p[i]/w[i];

P+=p[i];/

W+=w[i];/

}

if(W<=c)//装入所有物品

return P;

//依照物品单位重量降序排序

float f;

for( i=1; i

for(int j=0; j

{

if(Q[j]<=Q[j+1])

{

f=Q[j].d;

Q[j].d=Q[j+1].d;

Q[j+1].d=f;

}

}

Knap K;

K.p=new int [n+1];

K.w=new int [n+1];

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

{

K.p[i]=p[Q[i-1].ID];

K.w[i]=w[Q[i-1].ID];

}

K.cp=0;

K.cw=0;

K.c=c;

K.n=n;

K.bestp=0;

K.Backtrack(1);//从根开始搜索解空间树

delete[] Q;

delete[] K.w;

delete[] K.p;

return K.bestp;

}

int main()

{

int *p,*w,c,n;

int a[100];

int k=0;

while(cin>>n>>c && n+c)

{

w=new int [n+1];

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

cin>>w[i];

w[0]=0;

p=new int [n+1];

p[0]=0;

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

cin>>p[i];

a[k]=Knapsack(p,w,c,n);

k++;

}

for(int i=0; i

{

cout<

}

return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值