动态规划之01背包,完全背包,多重背包模板
2017-08-24 15:46
483 查看
自己整理的模板,记录一下:
#include <iostream> #include <vector> #include <deque> #include <algorithm> using namespace std; const int M = 500; const int N = 500; #pragma region"01背包问题" // 未优化版 int pack01(vector<int>& weight, vector<int>& value, int sum, int n) { int dp[M] ; for (int i = 0; i <= sum; ++i) { dp[0][i] = i >= weight[0] ? value[0] : 0; } for (int i = 1; i < n; ++i) { for (int v = weight[i]; v <= sum; ++v) { dp[i][v] = max(dp[i - 1][v], dp[i - 1][v - weight[i]] + value[i]); } } return dp[n - 1][sum]; } // 空间优化版(滚动数组) int pack01optimize(vector<int>& weight, vector<int>& value, int sum, int n) { int dp ; for (int i = 0; i <= sum; ++i) { dp[i] = i >= weight[0] ? value[0] : 0; } for (int i = 1; i < n; ++i) { for (int v = sum; v >= weight[i]; --v) { dp[v] = max(dp[v], dp[v - weight[i]] + value[i]); } } return dp[sum]; } #pragma endregion #pragma region"完全背包问题" // 完全背包问题(每个物品可以选无数次) int packComplete(vector<int>& weight, vector<int>& value, int sum, int n) { int dp ; for (int i = 0; i <= sum; ++i) { dp[i] = i >= weight[0] ? (dp[i - weight[0]] + value[0]) : 0; } for (int i = 1; i < n; ++i) { for (int v = weight[i]; v <= sum; ++v) // 和01背包的区别 { dp[v] = max(dp[v], dp[v - weight[i]] + value[i]); } } return dp[sum]; } #pragma endregion #pragma region"多重背包" #pragma region"二进制优化版" void oneZeroPack(int dp[], int sum, int weight, int value) { for (int i = sum; i >= weight; --i) { dp[i] = max(dp[i], dp[i - weight] + value); } } void completePack(int dp[], int sum, int weight, int value) { for (int i = weight; i <= sum; ++i) { dp[i] = max(dp[i], dp[i - weight] + value); } } // 把每个物体分成1, 2, 4 ..., 2^(k - 1), cnt - 2^k + 1个,然后转变成01背包问题,其中k为满足cnt - 2^k + 1 > 0的最大整数 int MultiPack(vector<int>& weight, vector<int>& value, vector<int>& cnt, int sum, int n) { int dp = {}; for (int i = 0; i < n; ++i) { if (weight[i] * cnt[i] >= sum) { completePack(dp, sum, weight[i], value[i]); } else { int k = 1; for (k = 1; k <= cnt[i]; k <<= 1) { oneZeroPack(dp, sum, weight[i], value[i]); cnt[i] -= k; } if (cnt[i]) { oneZeroPack(dp, sum, weight[i], value[i]); } } } return dp[sum]; } #pragma endregion #pragma region"单调队列版" struct Pack { int num, value; Pack(int _num, int _value) : num(_num), value(_value) { } }; deque<Pack> q; int multiPackQueue(vector<int>& weight, vector<int>& value, vector<int>& cnt, int sum, int n) { int dp ; for (int i = 0; i < n; ++i) { if (cnt[i] > (sum / weight[i])) cnt[i] = sum / weight[i]; for (int d = 0; d < weight[i]; ++d) { q.clear(); for (int j = 0; j <= (sum - d) / weight[i]; ++j) { int tValue = dp[d + j * weight[i]] - j * value[i]; while (!q.empty() && q.back().value <= tValue) q.pop_back(); q.push_back(Pack(j, tValue)); while (!q.empty() && q.front().num < j - cnt[i]) q.pop_front(); dp[d + j * weight[i]] = q.front().value + j * value[i]; } } } return dp[sum]; } #pragma endregion #pragma endregion
相关文章推荐
- 动态规划之01背包,完全背包,分组背包
- 动态规划之01背包、完全背包问题
- 动态规划:01背包、完全背包
- HDU-CRB and His Birthday(动态规划本质未认清)---01背包与完全背包的结合!
- 背包模板(01,完全,多重背包的二进制优化和单调队列优化
- NYOJ - 995 - 硬币找零(动态规划-完全背包)
- HDU 2159(动态规划-完全背包)
- 动态规划--背包问题(0-1背包,完全背包,多重背包)
- 完全背包 多种解法 动态规划
- 动态规划的两个经典问题--01背包
- 动态规划之背包问题01——Java实现
- 动态规划之背包01
- POJ_3181_Dollar_Dayz_(动态规划,完全部分和,完全背包)
- 算法导论学习笔记(十三):动态规划(三):01背包问题
- 01背包,完全背包,模板
- uva 147 - Dollars(动态规划--完全背包)
- 动态规划01背包
- 杭电ACM OJ 1011 Starship Troopers 树的动态规划(树的dp)经典树形背包 java写的 包看懂 递归流程完全解析
- 01背包之动态规划
- 背包之01,完全,多重模板