0-1背包问题(回溯算法)


#include<iostream>
#include<algorithm>
using namespace std;

#define NUM 100
int c;	//容量 
int n;	//数量 
int cw;	//当前重量 
int cv;	//当前价值 
int bestv;	//最优价值 

struct Object{
	int w;
	int v;
	double d;	//物品的单位重量价值比 
}Q[NUM];

bool cmp(Object a, Object b)
{
	if(a.d>=b.d) return true;
	else return false;
}

int Bound(int i)
{
	int cleft = c-cw;	//背包剩余的容量 
	int b = cv;
	while (i<n && Q[i].w<=cleft)
	{
		cleft -= Q[i].w;
		b += Q[i].v;
		i++;
	}
	if (i<n) b += cleft*Q[i].d;
	return b;
}

void backtrack(int i) //形参i是回溯的深度 
{
	if (i+1>n) 
	{
		bestv = cv; 
		return;
	}
	if (cw+Q[i].w<=c)
	{
		cw += Q[i].w;
		cv += Q[i].v;
		backtrack(i+1);
		cw -= Q[i].w;
		cv -= Q[i].v;
	}
		
	if (Bound(i+1)>bestv) 
	{
		backtrack(i+1);
	}
		
}

int main()
{
	while(scanf("%d%d",&n,&c))
	{
		cw = 0;
		cv = 0;
		bestv = 0;
		for(int i=0; i<n; i++)
			scanf("%d",&Q[i].w);
		for(int i=0; i<n; i++)
			scanf("%d",&Q[i].v);
		for(int i=0; i<n; i++)
			Q[i].d = 1.0*Q[i].v/Q[i].w;
		sort(Q, Q+n, cmp);
		backtrack(0);
		printf("%d\n", bestv);
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值