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

#include<iostream>
#include<algorithm>

using namespace std;

struct object{
	float price;
	float weight;
	float value;
	object(){
		price = weight = value = 0;
	}
};

int n;
object objects[101];
int solve[101], yes[101];
float total_w, current_w = 0, current_p = 0; //total_weight current_weight
float max_price = 0;

int Cmp(object a, object b){
	return a.value > b.value;
}

float Bound(int i){
	float left_w = total_w - current_w;
	float bound = current_p;
	while(i <= n && left_w >= objects[i].weight){
		left_w -= objects[i].weight;
		bound += objects[i].price;
		i++;
	}
	//装满
	if(i <= n) bound += objects[i].value * left_w;
	return bound; 
}

void Knapsack(int i){
	if(i > n && current_p > max_price){
		for(int k = 1; k <= n; k++){
			solve[k] = yes[k];
		}
		max_price = current_p;
		return ;
	}
	if(current_w + objects[i].weight <= total_w){
		//if this object can be put in the bag, enter the left node
		current_w += objects[i].weight;
		current_p += objects[i].price;
		yes[i] = 1;
		Knapsack(i + 1);
		current_w -= objects[i].weight;
		current_p -= objects[i].price;
	
	}
	//enter the right node
	if(Bound(i + 1) > max_price){
		yes[i] = 0;
		Knapsack(i + 1);
	}
}

int main(){
	cout << "Please input the number of objects:" << endl;
	cin >> n;
	cout << "Please input the price of each object in order:" << endl;
	for(int i = 1; i <= n; i++) cin >> objects[i].price;
	cout << "Please input the weight of each object in order:" << endl;
	for(int i = 1; i <= n; i++){
		cin >> objects[i].weight;
		objects[i].value = objects[i].price / objects[i].weight;
	}
	cout << "Please input the total weight of the knapsack:" << endl;
	cin >> total_w;
	//sort
	sort(objects + 1, objects + n + 1, Cmp);
	Knapsack(1);
	cout << "These objects have been sorted in order:" << endl;
	for(int i = 1; i <= n; i++){
		cout << "No." << i << " price:" << objects[i].price << " weight:" << objects[i].weight
		<< " value:" << objects[i].value << endl;
	}
	cout << "The maximum of value is: " << max_price << endl;
	for(int i = 1; i <= n; i++){
		if(solve[i] == 0) cout << "not ";
		cout << "choose the object whose index is " << i << '.' << endl; 
	}
	return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值