Knapsack Problem
背包九讲
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相关推荐
- JavaScript实现Knapsack problem背包问题算法(附完整源码)
JavaScript实现Knapsack problem背包问题算法(附完整源码) Comparator.js完整源代码 Sort.js完整源代码 MergeSort.js完整源代码 Knapsack ...
- 动态规划法(四)0-1背包问题(0-1 Knapsack Problem)
继续讲故事~~ 转眼我们的主人公丁丁就要离开自己的家乡,去大城市见世面了.这天晚上,妈妈正在耐心地帮丁丁收拾行李.家里有个最大能承受20kg的袋子,可是妈妈却有很多东西想装袋子里,已知行李的编 ...
- [Algorithmic Toolbox学习笔记][week6]0/1 Knapsack Problem
问题描述 具体的问题描述请参考以下链接: [Algorithmic Toolbox学习笔记][week3]战利品的最大价值_Karen_AMPM的博客-CSDN博客假设小偷有一个背包只能放下一定重量的 ...
- Dynamic Programming 01 —knapsack problem(动态规划背包问题)
首先引入动态变化的含义:为什么要有动态规划? Introduction: 从斐波那契函数的递归中我们发现,在例子求fib(7)的过程中,我们需求得fib(5)和fib(6),而我们在求fib(6)的时 ...
- C#,背包问题(Knapsack Problem)贪心算法的源代码
背包问题(KnapSack Problem)的相关算法是常用的规划算法. 一.什么是背包问题? 背包的问题是,你有一个"袋子",可以装有限数量的物品,鉴于你有一组物品可以从每个物品 ...
- Python多维约束(重量+体积+次数)背包问题(Knapsack Problem)
问题描述:1.一个背包,往里装东西,物品重量w(weight)对应为[2,3,4,7] ,价值va(value)对应为[1,4,7,12] ,如果你的最大承重为20,每个物品可装次数不限,求你能装入背 ...
- 背包问题(Knapsack problem)采用动态规划求解
问题说明: 假设有一个背包的负重最多可达8公斤,而希望在背包中装入负重范围内可得之总价物 品,假设是水果好了,水果的编号.单价与重量如下所示: 0 李子 4KG NT$4500 1 苹果 5KG NT ...
- 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 ...
- 【 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 ...
最新文章
- Cordova error:npm install -g ios-deploy
- python3入门书籍-学习python3入门书籍选哪些?
- Java的时间为何从1970年1月1日开始
- STM32开发 -- 4G模块开发详解(3)
- php+静态变量的初始值,php 静态变量的初始化
- 如何优雅的实现一个靠谱的RTSP播放器?
- ZZULIOJ 1058: 求解不等式
- 单体预聚合的目的是什么_第七章 配位聚合
- 原来这样做模型分数,稳定性与灵活性可以双保障!
- Win11如何使用多桌面功能?Win11使用多桌面功能的方法
- markown编辑器截图粘贴预览,并将图片传至七牛云
- [Pytorch]PyTorch Dataloader自定义数据读取
- 学习 LLVM(11) iplist 和 ilist
- 冯 诺依曼计算机体系结构要点,冯诺依曼体系结构计算机的要点和工作过程
- 微信群发提示频繁怎么办?
- 基于罗格里德矩阵的坐标转换7参数求取
- python 百度智能完善拆分识别收货人地址
- 最大子串和【浙江工商大学oj】【详细注释版】
- 自动驾驶系统入门(九)- 无人驾驶客户端系统
- Qt3升级 -Qt论坛问答翻译