编程练习:动态规划0-1背包问题
2016-09-28 11:19
253 查看
原理参考此篇,写的很好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
={0,2,2,6,5,4},物品价值V
={0,6,3,5,4,6},
(第0位,置为0,不参与计算,只是便于与后面的下标进行统一,无特别用处,也可不这么处理。)总重量c=10.
Ø背包的最大容量为10,那么在设置数组m大小时,可以设行列值为6和11,那么,对于m(i,j)就表示可选物品为i…n背包容量为j(总重量)时背包中所放物品的最大价值。
接下来是在笔试中遇到的问题,首先应根据题意归结出是什么问题,在根据相应的基本问题解法做相应修改即可。
问题描述
炉石游戏单张卡牌有卡牌消耗水晶和伤害,给定水晶上限和卡牌数量,并输入卡牌尺寸,求最大伤害。
关键地推公式为:
f(n)=⎧⎩⎨maxm(i+1,j),m(i+1,j−w1)+vi,max(m(i+1,j)),if j≤wiif 0≤j<wi
动态规划0-1背包问题
Ø
问题描述:
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应如何选择装入背包的物品,使得装
入背包中物品的总价值最大?
Ø
对于一种物品,要么装入背包,要么不装。所以对于一种物品的装入状态可以取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题。
过程分析
数据:物品个数n=5,物品重量w
={0,2,2,6,5,4},物品价值V
={0,6,3,5,4,6},
(第0位,置为0,不参与计算,只是便于与后面的下标进行统一,无特别用处,也可不这么处理。)总重量c=10.
Ø背包的最大容量为10,那么在设置数组m大小时,可以设行列值为6和11,那么,对于m(i,j)就表示可选物品为i…n背包容量为j(总重量)时背包中所放物品的最大价值。
接下来是在笔试中遇到的问题,首先应根据题意归结出是什么问题,在根据相应的基本问题解法做相应修改即可。
问题描述
炉石游戏单张卡牌有卡牌消耗水晶和伤害,给定水晶上限和卡牌数量,并输入卡牌尺寸,求最大伤害。
关键地推公式为:
f(n)=⎧⎩⎨maxm(i+1,j),m(i+1,j−w1)+vi,max(m(i+1,j)),if j≤wiif 0≤j<wi
#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; }
相关文章推荐
- SDAU 编程练习三 动态规划和动态规划与背包问题相结合的问题
- 程序设计实习动态规划练习 Charm Bracelet(0/1背包问题dp)
- 开始学习动态规划---先解决下背包问题
- 0/1背包问题动态规划详解
- 01背包问题动态规划详解
- 0/1背包问题动态规划详解之一
- 动态规划解决0-1背包问题
- 01背包问题动态规划详解(转载)
- 0/1背包问题动态规划详解
- 动态规划_背包问题扩展
- 动态规划——背包问题变形 收藏
- 0-1背包问题的动态规划解法
- 动态规划解0-1背包问题
- 动态规划——背包问题变形
- 0/1背包问题动态规划详解
- 0-1背包问题的动态规划解法为什么是NPC问题?
- 背包问题与动态规划问题初学
- 0-1背包问题;动态规划;时间复杂度O(n方);给出最大价值与解得情况;内有动态规划思路总结;
- 背包问题动态规划求解
- 动态规划解背包问题/C++/Knapsack problem