問題:
假設有n個物品,每個物品都是有重量的,同時每個物品也是有價值的,要求把這些物品放到一個揹包中,這個揹包的載重量是有限制的,怎麼使得揹包裏面的物品總價值最大?
符號表示:
N:物品個數
W:揹包載重量
w[i]:物品i的重量(1<i<=N)
v[i]:物品i的價值(1<i<=N)
c[i, j]:到物品i爲止,揹包重量限制爲j的最優解(1<i<=N, 1<j<=W)
分析:
- 最優解結構:對於物品i,只有兩種情況,放入或不放入。假設物品i放入了是最優解的一部分,那麼我們這時候拿掉物品i,c[i-1, j-w[i]]也應該是最優解
- 遞歸定義最優解的值:
- 按自底向上的方式計算最優值:雙重循環,i從1到N循環,j從1到W循環
- 由計算出的結果構造一個最優解:自頂向下,i從N到1循環,如果c[i,j]>c[i-1,j],則物品i放入揹包,否則反之。
#ifndef ___1package__package__
#define ___1package__package__
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Package{
public:
void init(string dataSource);
void print();
private:
void compute();
int m_nN; // The number of object
int m_nW; // The max weight of package
vector<int> m_vecWeight; // The weight of object
vector<int> m_vecValue; // The value of object
vector<vector<int> > m_vecMatrix; // The results matrix
};
#endif /* defined(___1package__package__) */
//
// package.cpp
// 01package
#include "package.h"
#include <fstream>
void Package::init(string dataSource){
// read data from datasource
ifstream file;
file.open(dataSource);
if (file.is_open()){
string buffer;
file>>m_nW;
file>>m_nN;
m_vecWeight.clear();
m_vecWeight.push_back(0);
m_vecValue.clear();
m_vecValue.push_back(0);
int w, v;
for (int i=0; i<m_nN; ++i) {
file>>w>>v;
m_vecWeight.push_back(w);
m_vecValue.push_back(v);
}
while(!file.eof()){
file>>buffer;
cout<<buffer<<endl;
}
}
file.close();
m_vecMatrix.clear();
// set first row and first column to zero
for (int i=0; i<=m_nN; ++i) {
m_vecMatrix.push_back(vector<int>(m_nW+1, 0));
}
}
void Package::print(){
compute();
cout<<"\n=====The Results======\n"<<"The max value: "<<m_vecMatrix[m_nN][m_nW]<<endl;
}
void Package::compute(){
for (int i=1; i<=m_nN; ++i) {
for (int j=1; j<=m_nW; ++j) {
int cur_weight = m_vecWeight[i];
if (cur_weight>j) {
m_vecMatrix[i][j] = m_vecMatrix[i-1][j];
} else{
m_vecMatrix[i][j] = max<int>(m_vecMatrix[i-1][j-cur_weight]+m_vecValue[i], m_vecMatrix[i-1][j]);
}
}
}
}
輸入的測試數據可以參考:http://zhidao.baidu.com/question/77646243.html