动态规划
利用动态规划进行解决,动态规划的思想就是将大问题化为小问题,求出小问题的解已备在解决大问题中进行使用,而不需要重复计算的方法。即:最优子结构+重叠子问题。
动态规划解决问题:两本质三特点四要素。
本质:对问题状态的定义。状态转移方程的定义。
特点:将一个大问题分割成N个相似小问题。N个小问题只需计算一次。存储N个小问题的解。
要素:状态的定义,状态转移方程的状态变化定义,状态初始化,状态结果。
题目描述
有 KindCount 个物品和一个大小为 PackSize的背包. 给定数组 KindG表示每个物品的大小和数组 KindV 表示每个物品的价值.
问最多能装入背包的总价值是多大?
解题思路:
利用动态规划进行划分为小问题即从当只有一个大小背包一个物品时开始进行判断。如果可以放进去,便需要计算放进去与不放进去的时两者中哪一个最大便取其最大的,如果不放就是它的包大小-1的上一个最大最大价值,放就是包大小-放入这个物品的大小时的最大价值+该物品的最大价值。以此类推。将小问题递推为最终的大问题。
代码实现:
#include<iostream> #include<algorithm> #include<vector> using namespace std; void Dispose(int& PackSize, int& KindCount, vector<int>& KindG, vector<int>& KindV) { vector<vector<int>> DisposeTable(KindCount + 1, vector<int>(PackSize + 1, 0)); for (int i = 1; i <= KindCount; i++) { for (int j = 1; j <= PackSize; j++) { if (KindG[i - 1] > j) { DisposeTable[i][j] = DisposeTable[i][j -1]; } else//如果可以装进去 { //将该物品装进去计算价值大小 int NewData = DisposeTable[i - 1][j - KindG[i - 1]] + KindV[i - 1]; //将装与不装进行比较,取最大值 DisposeTable[i][j] = max(NewData, DisposeTable[i - 1][j]); } } } cout << "背包大小为: " << PackSize << " 所能装的最大价值是: " << DisposeTable[KindCount][PackSize] << endl; } int main() { int PackSize = 0; int KindCount = 0; vector<int> KindG; vector<int> KindV; while (cin >> PackSize >> KindCount) { int temp; for (int i = 0; i < KindCount; i++) { cin >> temp; KindG.push_back(temp); } for (int i = 0; i < KindCount; i++) { cin >> temp; KindV.push_back(temp); } if (PackSize > 0 && KindCount > 0) { Dispose(PackSize, KindCount, KindG, KindV); } } return 0; }
代码运行:
珍&源码