0-1背包问题
问题描述:
给定 n 个物品和一个容量为 C 的背包,请 给出物品装入背包的方案,使得背包中物品的总价值 M 最大,并 满足:
• 每个物品 I 的重量为 w i ,价值为 v i 。
• 每个物品不可拆分,要么完整装入背包,要么不在背包里。
• 背包中物品的总重量不能超过容量 C 。
// Pack.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
template<class Type>
class Knap
{
friend void Knapsack(int *w,int *p);
private:
void Output();
Type Bound(int i);
void Backtrack(int t);
Type c,//这个背包的容量
* w,//物品的重量
* p,//物品的价值
cw,//当前的重量
* x;
float cp,//当前的价值
bestp;//最好的价值
int n;//物品的数量
};
void Knapsack(int* w, int* p)
{
Knap<int> knap;
knap.w = w;
knap.p = p;
knap.n = 4;
knap.c = 7;
knap.cw = 0;
knap.cp = 0;
knap.bestp = 0;
knap.x = new int[knap.n + 1];
memset(knap.x, 0, (knap.n + 1) * sizeof(int));
knap.Output();
std::cout << "_______________________" << std::endl;
knap.Backtrack(1);
}
template<class Type>
void Knap<Type>::Backtrack(int t)
{
if (t > n)
{
if (cp > bestp)
{
bestp = cp;
for (int i = 1; i <= n; i++)
std::cout << x[i] << "\t";
std::cout << std::endl;
std::cout << bestp << std::endl;
}
return;
}
if(cw+w[t]<=c)
{
cw += w[t];
cp += p[t];
x[t] = 1;
Backtrack(t + 1);
cw - w[t];
cp -= p[t];
x[t] = 0;
}
if(Bound(t+1)>bestp)
Backtrack(t + 1);
}
template<class Type>
Type Knap<Type>::Bound(int t)//求得时背包的价值
{
Type clear = c - cw;//剩余的容量
Type b = cp;//当前的价值
while (clear>w[t]&&t<=n)
{
clear -= w[t];
b += p[t];
t++;
}//剩余容量还可以添加的价值
if (t <= n)//不能装下整个物品时,转下部分
b += p[t] * clear / w[t];
return b;
}
template<class Type>
void Knap<Type>::Output()
{
std::cout << "这个背包的容量:" << c << "物品的数量:" << n << "最好的价值:" << bestp
<< "当前的价值:" << cp << "当前的重量:" << cw << std::endl;
for (int i = 1; i <= n; i++)
std::cout << w[i] << "\t";
std::cout << std::endl;
for (int i = 1; i <= n; i++)
std::cout << p[i] << "\t";
std::cout << std::endl;
for (int i = 1; i <= n; i++)
std::cout << x[i] << "\t";
std::cout << std::endl;
}
int main()
{
int n = 4;
int* w,*p;
w = new int[n + 1];
w[0] = 0, w[1] = 3, w[2] = 5, w[3] = 2, w[4] = 1;
p = new int[n + 1];
p[0] = 0, p[1] = 9, p[2] = 10, p[3] = 7, p[4] = 4;
Knapsack(w, p);
return 0;
}