第一种方法:
我们从第一个物品开始选择,此时背包的剩余空间为weight;然后选择第二个物品,此时有两种情况,一是将该物品装入背包里,二是不将该物品装入背包里;
ret = max(package_0_1(num + 1, things, weight - things[num].first) + things[num].second, package_0_1(num + 1, things, weight));
。。。。直到将选择完最后一个物品;这种方法的搜索深度是n,每一层的搜索都需要两个分支,最坏就是需要O(2^n);
第二种方法:
第一种方法有一个重复判断问题;递归调用函数的时候会重复执行相同的情况,所以我们采取一种方法来规避这种重复操作;
用一个二维数组记录递归函数执行的每一种情况,总共有n*m中情况,所以最多执行n*m次递归函数;时间复杂度变为O(n*m);
ret = max(package_0_1_advanced(num + 1, things, weight - things[num].first) + things[num].second, package_0_1_advanced(num + 1, things, weight));
第一种方法:
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>//pair, make_pair
using namespace std;
/*********************************************************************
参数num表示当前第num个物品
参数weight表示当前背包剩下的容量
things中的成员的first表示物品的质量,second表示物品的价值
*********************************************************************/
int package_0_1(int num, vector<pair<int, int> > & things, int weight)
{
int ret;
if (num == things.size()){
ret = 0;
}
else if (weight < things[num].first){//当前背包剩下的空间weight不能装入第num个物品,所以继续选择下一个物品
ret = package_0_1(num + 1, things, weight);
}
else{//当前背包剩下的空间weight可以装入第num个物品,但是我们有两个选择可以装入和不装入,返回比较大的那个情况,返回的价值的大小
ret = max(package_0_1(num + 1, things, weight - things[num].first) + things[num].second, package_0_1(num + 1, things, weight));
//package_0_1(num + 1, things, weight - things[num].first) + things[num].second是选择装入第num个物品
}
return ret;
}
void input_data(int *number, vector<pair<int, int> > & things, int * total_weight)
{
cout << "Input the number of things: ";
cin >> *number;
cout << "Input the things' weight and value:\n";
int weight, value;
for (int i = 0; i < *number; ++i){
cin >> weight;
cin.get();
cin >> value;
cin.get();
things.push_back(make_pair(weight, value));
}
cout << "Input total weight: ";
cin >> *total_weight;
}
int main()
{
int total_weight;//背包总的容量
int number;//物品的个数
vector<pair<int, int> > things;//pair<int, int> 表示物品的质量和价值的组合
input_data(&number, things, &total_weight);
/* //仅仅是为了测试输入的数据对不对
cout << "Output the things: ";
for (int i = 0; i < things.size(); ++i){
cout << things[i].first << "," << things[i].second << " ";
}
cout << endl;
*/
int max_value = package_0_1(0, things, total_weight);//背包可以装入的物品的最大价值
cout << "max value is " << max_value << endl;
system("pause");
return 0;
}
第二种方法:
#include <iostream>
#include <vector>
#include <algorithm>
#include <utility>//pair, make_pair
using namespace std;
#define MAXNUMBER 100
#define MAXWEIGHT 10000
int book[MAXNUMBER][MAXWEIGHT];//记忆数组
/*********************************************************************
参数num表示当前第num个物品
参数weight表示当前背包剩下的容量
things中的成员的first表示物品的质量,second表示物品的价值
*********************************************************************/
int package_0_1_advanced(int num, vector<pair<int, int> > & things, int weight)
{
if (book[num][weight] >= 0){//如果此时判断它的值大于等于0,则表示已经判断过这种情况,直接返回;
return book[num][weight];
}
int ret;
if (num == things.size()){
ret = 0;
}
else if (weight < things[num].first){//当前背包剩下的空间weight不能装入第num个物品,所以继续选择下一个物品
ret = package_0_1_advanced(num + 1, things, weight);
}
else{//当前背包剩下的空间weight可以装入第num个物品,但是我们有两个选择可以装入和不装入,返回比较大的那个情况,返回的价值的大小
ret = max(package_0_1_advanced(num + 1, things, weight - things[num].first) + things[num].second, package_0_1_advanced(num + 1, things, weight));
//package_0_1(num + 1, things, weight - things[num].first) + things[num].second是选择装入第num个物品
}
book[num][weight] = ret;
return ret;
}
void input_data(int *number, vector<pair<int, int> > & things, int * total_weight)
{
cout << "Input the number of things: ";
cin >> *number;
cout << "Input the things' weight and value:\n";
int weight, value;
for (int i = 0; i < *number; ++i){
cin >> weight;
cin.get();
cin >> value;
cin.get();
things.push_back(make_pair(weight, value));
}
cout << "Input total weight: ";
cin >> *total_weight;
//初始化标志数组book, 比如book[i][j]的值记录的是第i个商品,背包剩下容量j的时候背包包含的价值;
//如果此时判断它的值大于等于0,则表示已经判断过这种情况,直接返回;
//如果此时判断它的值还是小于0,则表示还没有判断过这种情况;
memset(book, -1, sizeof(book));//将该数组的初值置为-1
}
int main()
{
int total_weight;//背包总的容量
int number;//物品的个数
vector<pair<int, int> > things;//pair<int, int> 表示物品的质量和价值的组合
input_data(&number, things, &total_weight);
/* //仅仅是为了测试输入的数据对不对
cout << "Output the things: ";
for (int i = 0; i < things.size(); ++i){
cout << things[i].first << "," << things[i].second << " ";
}
cout << endl;
*/
int max_value = package_0_1_advanced(0, things, total_weight);//背包可以装入的物品的最大价值
cout << "max value is " << max_value << endl;
system("pause");
return 0;
}
比较好的参考链接:
http://www.cnblogs.com/daoluanxiaozi/archive/2012/05/06/2486105.html
http://shmilyaw-hotmail-com.iteye.com/blog/2009761