原理參考此篇,寫的很好http://blog.csdn.net/dapengbusi/article/details/7463968
- 動態規劃0-1揹包問題
Ø
問題描述:
給定n種物品和一揹包。物品i的重量是wi,其價值爲vi,揹包的容量爲C。問應如何選擇裝入揹包的物品,使得裝
入揹包中物品的總價值最大?
Ø
對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1.我們設物品i的裝入狀態爲xi,xi∈ (0,1),此問題稱爲0-11揹包問題。
過程分析
數據:物品個數n=5,物品重量w[n]={0,2,2,6,5,4},物品價值V[n]={0,6,3,5,4,6},
(第0位,置爲0,不參與計算,只是便於與後面的下標進行統一,無特別用處,也可不這麼處理。)總重量c=10.
Ø揹包的最大容量爲10,那麼在設置數組m大小時,可以設行列值爲6和11,那麼,對於m(i,j)就表示可選物品爲i…n揹包容量爲j(總重量)時揹包中所放物品的最大價值。
接下來是在筆試中遇到的問題,首先應根據題意歸結出是什麼問題,在根據相應的基本問題解法做相應修改即可。
- 問題描述
爐石遊戲單張卡牌有卡牌消耗水晶和傷害,給定水晶上限和卡牌數量,並輸入卡牌尺寸,求最大傷害。
關鍵地推公式爲:
#include<iostream>
#include<vector>
#include<algorithm>
#include<exception>
using namespace std;
//函數定義
//模板類matrix頭文件定義
template<class T>
class matrix
{
public:
matrix(int rows = 1, int cols = 1, const T&value = T()); //構造函數
vector<T>&operator[](int i); //提領運算
const vector<T>&operator[](int i)const; //提領預算
int rows()const{ return row; } //矩陣行數
int cols()const{ return col; } //矩陣列數
void resize(int rows, int cols); //重置矩陣大小
void print_matrix(ostream&out)const; //矩陣輸出
private:
int row, col; //矩陣行數和列數
vector<vector<T>>mat; //向量表示的矩陣
};
//定義自己的異常
class MyMatIndUnboundException :public exception
{
virtual const char* what() const throw()
{
return "matrix index cross boarder!";
}
}myExcept;
//子函數實現功能
//構造函數
template<class T>
matrix<T>::matrix(int rows, int cols, const T& value) :row(rows), col(cols), mat(rows, vector<T>(cols, value))
{
}
//提領函數
template<class T>
vector<T>& matrix<T>::operator[](int i)
{
if (i < 0 || i >= row)throw myExcept;
return mat[i];
}
template<class T>
const vector<T>& matrix<T>::operator[](int i) const
{
if (i < 0 || i >= row)throw myExcept;
return mat[i];
}
//重置矩陣大小
template<class T>
void matrix<T>::resize(int rows, int cols)
{
if (rows == row&&cols == col)
return;
row = rows, col = cols;
mat.resize(row); //重置行數
for (int i = 0; i < row; i++)
mat[i].resize(col); //重置列數
}
//打印矩陣元素
template<class T>
void matrix<T>::print_matrix(ostream&out)const
{
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
cout << mat[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
int main()
{
//定義消耗水晶數和卡牌數量
int N, M; //N爲水晶數
cin >> N >> M;
vector<int> cardConsu;
cardConsu.push_back(0);
vector<int> damage;
damage.push_back(0);
//輸入卡牌身材
int singleCardConSu;
int singleCardDam;
while (cin >> singleCardConSu >> singleCardDam)
{
cardConsu.push_back(singleCardConSu);
damage.push_back(singleCardDam);
}
matrix<int> Mat(M + 1, N + 1, 0);
int i = 1;
int j = 1;
for (i = 1; i <= M; i++)
{
for (j = 1; j <= N; j++)
{
// 遞推關係式出爐
if (j < cardConsu[i])
{
Mat[i][j] = Mat[i - 1][j];
}
else
{
int x = Mat[i - 1][j];
int y = Mat[i - 1][j - cardConsu[i]] + damage[i];
Mat[i][j] = x < y ? y : x;
}
}
}
Mat.print_matrix(cout);
int max = 0;
for (int i = 0; i <M+1; i++)
{
for (int j = 0; j <N+1; j++)
{
if (Mat[i][j] > max)
max = Mat[i][j];
}
}
cout << max<<endl;
return 0;
}