背包九讲


0-1 knapsack problem

01背包-牛客网

已知一个背包最多能容纳体积之和为V的物品,现有 n 个物品,第 i 个物品的体积为 vi , 重量为 wi,求当前背包最多能装多大重量的物品?

使用动态规划来解决01背包问题:

首先定义dp数组:dp[i][j] := 0-i号物品面对容量为j的背包所能获得的最大重量

状态转移方程:

dp[i][j]={dp[i−1][j],容量不足,不放入物品imax(dp[i−1][j],dp[i−1][j−v[i]]+w[i]),考虑拿这件物品能否获得更大重量dp[i][j]= \begin{cases} dp[i-1][j],\quad 容量不足,不放入物品i\\ max(dp[i - 1][j], dp[i - 1][ j - v[i]] + w[i]), \quad 考虑拿这件物品能否获得更大重量 \end{cases} dp[i][j]={dp[i−1][j],容量不足,不放入物品imax(dp[i−1][j],dp[i−1][j−v[i]]+w[i]),考虑拿这件物品能否获得更大重量​

class Solution {public:int knapsack(int V, int n, vector<vector<int> >& vw) {vector<vector<int>> dp(n + 1, vector<int>(V + 1, 0));for (int i = 1; i <= n; ++i) {for (int j = 1; j <= V; ++j) {if (j < vw[i - 1][0]) {dp[i][j] = dp[i - 1][j];} else {dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vw[i - 1][0]] + vw[i - 1][1]);}}}return dp[n][V];}
};

由于dp问题具有无后效性,可以采用滚动数组的方式节省内存,此时状态转移方程化为:

if j >= v[i]:dp[j] = max(dp[j], dp[j - v[i]] + w[i]);

Charm Bracelet:定义一维的dp数组,每次从后向前刷新dp数组:

#include <iostream>
#include <vector>
using namespace std;int main() {int N, M;cin >> N >> M;vector<int> W(N, 0);vector<int> D(N, 0);vector<int> dp(M + 1, 0);for (int i = 0; i < N; ++i) {cin >> W[i] >> D[i];}for (int i = 0; i < N; ++i) {for (int j = M; j >= 1; --j) {if (j >= W[i]) {dp[j] = max(dp[j], dp[j - W[i]] + D[i]);}}}cout << dp[M] << endl;return 0;
}

full knapsack problem

完全背包-牛客网

你有一个背包,最多能容纳的体积是V。现在有n种物品,每种物品有任意多个,第 i 种物品的体积为vi,价值为wi,求这个背包至多能装多大价值的物品?

完全背包的状态转移方程和01背包极其相似:

dp[i][j]={dp[i−1][j],容量不足,不放入物品imax(dp[i−1][j],dp[i][j−v[i]]+w[i]),考虑拿这件物品能否获得更大重量dp[i][j]= \begin{cases} dp[i-1][j],\quad 容量不足,不放入物品i\\ max(dp[i - 1][j], dp[i][ j - v[i]] + w[i]), \quad 考虑拿这件物品能否获得更大重量 \end{cases} dp[i][j]={dp[i−1][j],容量不足,不放入物品imax(dp[i−1][j],dp[i][j−v[i]]+w[i]),考虑拿这件物品能否获得更大重量​
而且,考虑使用滚动数组压缩空间,完全背包和01背包的状态转移方程是一样的。区别在于dp数组的遍历方式:完全背包问题必须顺序推导dp数组,而01背包采用逆序推导dp数组

if j >= v[i]:dp[j] = max(dp[j], dp[j - v[i]] + w[i]);
class Solution {public:vector<int> knapsack(int v, int n, vector<vector<int> >& nums) {// write code herevector<int> res;vector<int> dp(v + 1, 0);vector<int> pack(v + 1, -255);pack[0] = 0;for (int i = 0; i < n; ++i) {for (int j = 0; j <= v; ++j) {if (j >= nums[i][0]){dp[j] = max(dp[j], dp[j - nums[i][0]] + nums[i][1]);pack[j] = max(pack[j], pack[j - nums[i][0]] + nums[i][1]);   //只考虑能从0一步步跳到v的w}}}res.push_back(dp[v]);if (pack[v] > 0) {res.push_back(pack[v]);} else {res.push_back(0);}return res;}
};

Piggy-Bank


fractional knapsack problem

与上面的两种背包问题不同,分数背包问题(物品可以被任意分割)比较简单,可以用贪心算法解决:每次都选择单位价值最大的物品装入背包,如果未满,则选择下一个价值次大的物品装入背包

圣诞老人的礼物-百练

#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;#define MAXN (100+10)struct Box {int v;int w;double density;Box() {}Box(int vv, int ww) :v(vv), w(ww), density(double(v) / w) {}bool operator<(const Box& b) {return density < b.density;}
};int n, weigth;
double total_w = 0;
double total_v = 0;
Box boxes[MAXN];int main() {cin >> n >> weigth;int v, w;for (int i = 0; i < n; ++i) {cin >> v >> w;boxes[i] = Box(v, w);}sort(boxes, boxes + n);for (int i = n - 1; i >= 0; --i) {if (total_w + boxes[i].w < weigth) {total_w += boxes[i].w;total_v += boxes[i].v;}else {total_v += boxes[i].density * (weigth - total_w);total_w = weigth;}}printf("%.1f\n", total_v);return 0;
}

Knapsack Problem相关推荐

  1. JavaScript实现Knapsack problem背包问题算法(附完整源码)

    JavaScript实现Knapsack problem背包问题算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 MergeSort.js完整源代码 Knapsack ...

  2. 动态规划法(四)0-1背包问题(0-1 Knapsack Problem)

      继续讲故事~~   转眼我们的主人公丁丁就要离开自己的家乡,去大城市见世面了.这天晚上,妈妈正在耐心地帮丁丁收拾行李.家里有个最大能承受20kg的袋子,可是妈妈却有很多东西想装袋子里,已知行李的编 ...

  3. [Algorithmic Toolbox学习笔记][week6]0/1 Knapsack Problem

    问题描述 具体的问题描述请参考以下链接: [Algorithmic Toolbox学习笔记][week3]战利品的最大价值_Karen_AMPM的博客-CSDN博客假设小偷有一个背包只能放下一定重量的 ...

  4. Dynamic Programming 01 —knapsack problem(动态规划背包问题)

    首先引入动态变化的含义:为什么要有动态规划? Introduction: 从斐波那契函数的递归中我们发现,在例子求fib(7)的过程中,我们需求得fib(5)和fib(6),而我们在求fib(6)的时 ...

  5. C#,背包问题(Knapsack Problem)贪心算法的源代码

    背包问题(KnapSack Problem)的相关算法是常用的规划算法. 一.什么是背包问题? 背包的问题是,你有一个"袋子",可以装有限数量的物品,鉴于你有一组物品可以从每个物品 ...

  6. Python多维约束(重量+体积+次数)背包问题(Knapsack Problem)

    问题描述:1.一个背包,往里装东西,物品重量w(weight)对应为[2,3,4,7] ,价值va(value)对应为[1,4,7,12] ,如果你的最大承重为20,每个物品可装次数不限,求你能装入背 ...

  7. 背包问题(Knapsack problem)采用动态规划求解

    问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物 品,假设是水果好了,水果的编号.单价与重量如下所示: 0 李子 4KG NT$4500 1 苹果 5KG NT ...

  8. FZU 2214 Knapsack problem(背包问题)

    Description 题目描述 Given a set of n items, each with a weight w[i] and a value v[i], determine a way t ...

  9. 【 FZU - 2214 】Knapsack problem(逆向0-1背包)

    题干: Given a set of n items, each with a weight w[i] and a value v[i], determine a way to choose the ...

最新文章

  1. Cordova error:npm install -g ios-deploy
  2. python3入门书籍-学习python3入门书籍选哪些?
  3. Java的时间为何从1970年1月1日开始
  4. STM32开发 -- 4G模块开发详解(3)
  5. php+静态变量的初始值,php 静态变量的初始化
  6. 如何优雅的实现一个靠谱的RTSP播放器?
  7. ZZULIOJ 1058: 求解不等式
  8. 单体预聚合的目的是什么_第七章 配位聚合
  9. 原来这样做模型分数,稳定性与灵活性可以双保障!
  10. Win11如何使用多桌面功能?Win11使用多桌面功能的方法
  11. markown编辑器截图粘贴预览,并将图片传至七牛云
  12. [Pytorch]PyTorch Dataloader自定义数据读取
  13. 学习 LLVM(11) iplist 和 ilist
  14. 冯 诺依曼计算机体系结构要点,冯诺依曼体系结构计算机的要点和工作过程
  15. 微信群发提示频繁怎么办?
  16. 基于罗格里德矩阵的坐标转换7参数求取
  17. python 百度智能完善拆分识别收货人地址
  18. 最大子串和【浙江工商大学oj】【详细注释版】
  19. 自动驾驶系统入门(九)- 无人驾驶客户端系统
  20. Qt3升级 -Qt论坛问答翻译

热门文章

  1. 互联网广告作弊与反作弊综述
  2. c语言单播,OSPF单播、多播及网络类型
  3. vue元旦倒计时烟花效果
  4. 网络工程师日常工作总结
  5. 09 Numpy中的常数
  6. Nginx 启动或重启失败原因总结及解决办法
  7. LeetCode刷题笔记-逃脱阻碍者
  8. 树莓派局域网测速方法
  9. C++ 因数分解(X * Y)
  10. “三体”域名纠纷案受关注,企业应如何做好域名品牌保护?