几个物品,重量不同,价值不同,有包一个,只能承受有限重量。请问,如何装包,才可以在不超载时候让包内物品价值最大?
写代码应该让变量名方法名见名知意。阅读程序时候对大脑想象力要求高,整些课本上的 i j k ,很快就整懵了,看了前面,忘了后面。而且有些逻辑未必真的清晰合理,或许还可以有继续优化的地方。
背包问题,先不着急写程序,从数学上理解,放开包大小不限,那么会有几种放法?每个物品有放包和不放包两种选择,n 个物品有 2^n 种选择。先从中排除掉总重量超载的,再从剩下的选法中找出价值最大的。
每次放入包时,核算总重量是否已超重,若已超重,肯定不能放,直接pass,对于不超重的也有放入包与不放包两种选择。
函数的三个参数:要考察的第 n 个物品序号,当前包中已有重量,当前包中已有价值。
代码如下 :本方法可能不是最快,但能解决总比没有强,菜鸟在学,谢谢 :
#include<iostream>
using namespace std;
#define ARRAYMAXLENGTH 100
int maxValue = 0;
bool maxSelect[ARRAYMAXLENGTH];
bool select[ARRAYMAXLENGTH];
int virtualNumber;
int bagSize;
int totalChooseNumber = 0;
struct {
int weight;
int value;
}stuff[ARRAYMAXLENGTH];
void choose(int index,int weightLoaded,int valueLoaded) {
if (index == virtualNumber) {
totalChooseNumber++;
cout << endl << "w v" << endl;
for (int i = 0; i < virtualNumber; i++)
if (select[i] == true)
cout << stuff[i].weight << " " << stuff[i].value << endl;
cout << "tatal :" << weightLoaded << " "<< valueLoaded << endl;
if (maxValue < valueLoaded) {
for (int i = 0; i < virtualNumber; i++)
maxSelect[i] = select[i];
maxValue = valueLoaded;
}
}
else if (weightLoaded + stuff[index].weight > bagSize)
choose(index + 1 ,weightLoaded,valueLoaded);
else {
select[index] = true;
choose(index + 1 ,weightLoaded + stuff[index].weight ,
valueLoaded + stuff[index].value);
select[index] = false;
choose(index + 1,weightLoaded,valueLoaded);
}
}
int main() {
cout << "virtrual number of stuffs : ";
cin >> virtualNumber;
for (int i = 0; i < virtualNumber; i++) {
cout << "input the " << (i + 1) << "th stuff weight and value : ";
cin >> stuff[i].weight >> stuff[i].value;
}
cout << "input bag size : ";
cin >> bagSize;
choose(0,0,0);
cout <<endl<< "result :" << endl<<"w v"<<endl;
for (int i = 0; i < virtualNumber; i++)
if (maxSelect[i] == true)
cout << stuff[i].weight << " " << stuff[i].value << endl;
cout <<"max value : "<< maxValue<<endl;
cout << "total choose option number : " << totalChooseNumber << endl;
return 0;
}
验证结果如下: