標籤:動態規劃 c++ 背包問題
問題:
假設有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放入背包,否則反之。
代碼(c++):
#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