编辑代码

#include<iostream>
#include<algorithm>
using namespace std;
 
 
class Knap {
	friend int knapsack(int *,int *,int ,int);
private:
	float 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);
		}
}
 
 
float Knap::Bound(int i) {
	//计算上界
	int cleft = c - cw; //剩余容量
	float b = cp;
	//以物品单位重量价值递减序装入物品
	while (i <= n && w[i] <= cleft) {
		cleft -= w[i];
		b += p[i];
		i++;
	}
	//装满背包
	if (i <= n){
		float aa=p[i] * cleft;
		float bb=w[i];
		float temp=aa/bb;

		b += temp;
		cout<<b<<endl;
	}
	return b;
};
class Object {
	friend int knapsack(int *,int *,int,int);
  public:
	int operator<=(Object a) const {
		return (d >= a.d);
	}
  private:
	int ID;
	float d;
};
 
 
int knapsack(int p[], int w[], int c, int n) {
	//为Knap: Backtrack初始化
	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];
		//cout<<Q[i - 1].d<<endl;
		P += p[i];
		W += w[i];
	}
	if (W <= c) return P; //装入所有物品
 
		for(int i = 1; i<n; i++)
 
			for(int j = 1; j<= n-i; j++)
 
			{
 
				if(Q[j-1].d < Q[j].d)
 
				{
 
					Object temp = Q[j-1];
 
					Q[j-1] = Q[j];
 
					Q[j] = temp;
 
				}
 
			}
 
    Knap K;
	K.p = new int[n + 1];
	K.w = new int[n + 1];
	for (int 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[]={0,5,3,5,3,2};
    int w[]={0,6,5,4,2,1};
    
	int c=knapsack(p,w,10,5);
	cout<<"01背包问题的最有值为:"<<c;
	return 0;
}