1. 算法思想

背包问题是一种组合优化的NP 完全问题。 所谓NP完全问题(NP-C问题),是世界七大数学难题之一。 NP的英文全称是Non-deterministic Polynomial的问题,即多项式复杂程度的非确定性问题

背包问题:有N 个物品和容量为W 的背包,每个物品都有自己的体积w 和价值v,求拿哪些物品可以使得背包所装下物品的总价值最大。

  • 如果限定每种物品只能选择0 个或1 个,则问题称为0-1 背包问题;
  • 如果不限定每种物品的数量,则问题称为无界背包问题或完全背包问题。

可以用动态规划来解决背包问题。

以0-1 背包问题为例。我们可以定义一个二维数组dp存储最大价值,其中dp[i][j] 表示前i 件物品体积不超过j 的情况下能达到的最大价值。在我们遍历到第i 件物品时,在当前背包总容量为j 的情况下,如果我们不将物品i 放入背包,那么dp[i][j] = dp[i-1][j],即前i 个物品的最大价值等于只取前i-1 个物品时的最大价值;如果我们将物品i 放入背包,假设第i 件物品体积为w,价值为v,那么我们得到dp[i][j] = dp[i-1][j-w] + v。我们只需在遍历过程中对这两种情况取最大值即可,总时间复杂度和空间复杂度都为O(NW)。

int knapsack(vector<int> weights, vector<int> values, int N, int W) {vector<vector<int>> dp(N + 1, vector<int>(W + 1, 0));for (int i = 1; i <= N; ++i) {int w = weights[i-1], v = values[i-1];for (int j = 1; j <= W; ++j) {if (j >= w) {dp[i][j] = max(dp[i-1][j], dp[i-1][j-w] + v);} else {dp[i][j] = dp[i-1][j];}}}return dp[N][W];
}

我们可以进一步对0-1 背包进行空间优化,将空间复杂度降低为O(W)。我们可以去掉dp 矩阵的第一个维度,在考虑物品i 时变成dp[j] = max(dp[j], dp[j-w] + v)。这里要注意我们在遍历每一行的时候必须逆向遍历,这样才能够调用上一行物品i-1 时dp[j-w] 的值;若按照从左往右的顺序进行正向遍历,则dp[j-w] 的值在遍历到j 之前就已经被更新成物品i 的值了。

int knapsack(vector<int> weights, vector<int> values, int N, int W) {vector<int> dp(W + 1, 0);for (int i = 1; i <= N; ++i) {int w = weights[i-1], v = values[i-1];for (int j = W; j >= w; --j) {dp[j] = max(dp[j], dp[j-w] + v);}}return dp[W];
}

在完全背包问题中,一个物品可以拿多次。如果仍采用这种方法,假设背包容量无穷大而物体的体积无穷小,我们这里的比较次数也会趋近于无穷大,远超O(NW) 的时间复杂度。因此,对于拿多个物品的情况,我们就得到了完全背包问题的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v),其与0-1 背包问题的差别仅仅是把状态转移方程中的第二个i-1 变成了i。

int knapsack(vector<int> weights, vector<int> values, int N, int W) {vector<vector<int>> dp(N + 1, vector<int>(W + 1, 0));for (int i = 1; i <= N; ++i) {int w = weights[i-1], v = values[i-1];for (int j = 1; j <= W; ++j) {if (j >= w) {dp[i][j] = max(dp[i-1][j], dp[i][j-w] + v);} else {dp[i][j] = dp[i-1][j];}}}return dp[N][W];
}

同样的,我们也可以利用空间压缩将时间复杂度降低为O¹Wº。这里要注意我们在遍历每一
行的时候必须正向遍历,因为我们需要利用当前物品在第j-w 列的信息。

int knapsack(vector<int> weights, vector<int> values, int N, int W) {vector<int> dp(W + 1, 0);for (int i = 1; i <= N; ++i) {int w = weights[i-1], v = values[i-1];for (int j = w; j <= W; ++j) {dp[j] = max(dp[j], dp[j-w] + v);}}return dp[W];
}

2. 常见题型

LeetCode-416. Partition Equal Subset Sum [C++][Java]_贫道绝缘子的博客-CSDN博客Given anon-emptyarraynumscontainingonly positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal.https://blog.csdn.net/qq_15711195/article/details/123451917LeetCode-474. Ones and Zeroes [C++][Java]_贫道绝缘子的博客-CSDN博客You are given an array of binary stringsstrsand two integersmandn. Returnthe size of the largest subset ofstrssuch that there areat mostm0's andn1's in the subset. A setxis asubsetof a setyif all elements ofxare also elements ofy.https://blog.csdn.net/qq_15711195/article/details/123454650LeetCode-322. Coin Change [C++][Java]_贫道绝缘子的博客-CSDN博客Returnthe fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return-1.https://blog.csdn.net/qq_15711195/article/details/123455088

LeetCode-494. Target Sum [C++][Java]_贫道绝缘子的博客-CSDN博客You are given an integer arraynumsand an integertarget. You want to build anexpressionout of nums by adding one of the symbols'+'and'-'before each integer in nums and then concatenate all the integers.https://blog.csdn.net/qq_15711195/article/details/123491394

参考文献

【1】算法基础:NP完全问题_清水河C罗——Leonardo-Liu-CSDN博客_np完全问题

LeetCode常见题型——背包问题相关推荐

  1. LeetCode常见题型——树

    1. 算法思想 作为(单)链表的升级版,我们通常接触的树都是二叉树(binary tree),即每个节点最多有 两个子节点:且除非题目说明,默认树中不存在循环结构. struct TreeNode { ...

  2. LeetCode常见题型——二分查找

    1. 算法思想 二分查找(又叫二分法,折半查找)每次在查找时通过将待查区间分为两部分并只取一部分继续查找.对于一个长度为O(n)的数组,二分查找的时间复杂度为O(log(n)). C++等语言习惯使用 ...

  3. 一文通数据结构与算法之——链表+常见题型与解题策略+Leetcode经典题

    文章目录 1 链表 1.1 常见题型及解题策略 1.1.1 LeetCode中关于链表的题目有以下五种类型题: 1.1.2 解题策略 1.2 链表的基本内容 1.2.1 链表的基本结构: 1.2.2 ...

  4. 全国计算机vb二级题型,全国计算机二级考VB机试常见题型汇总.doc

    全国计算机二级考VB机试常见题型汇总,计算机二级vb考试题型,计算机二级vb题型,vb二级考试题型,全国计算机二级vb题型,几何概型常见题型归类,线性规划的常见题型,解三角形常见题型,记叙文阅读常见题 ...

  5. 计算机学业水平测试初中生操作题,初中学业水平考试信息技术考试操作题常见题型及作答方法...

    初中信息技术考试操作题常见题型及作答方法 牛角寨乡初级中学 信息技术考试已经有两年了,通过这两年的考试情况来看,我认为,要想在信息技术考试中取得一个好的成绩,操作题是一个很重要的环节,从这两年的情况来 ...

  6. 泰勒公式的介绍、应用及常见题型

    目录 一.简介 1.泰勒公式及其证明过程 2.两种类型的余项 3.麦克劳林公式 二.泰勒公式常见题型 1.用泰勒公式展开函数 2.用泰勒公式求极限 3.用泰勒公式讨论无穷小的比较 4.用泰勒公式证明等 ...

  7. ctf之逆向常见题型

    开头 逆向的题型有很多很多种,那些没见过的,以后再说 写下这篇文章我顺便复习一下,好多东西都快忘了怎么做了,前面那些逆向基础知识,有什么用呢,就一个用,让你明白为什么要那么做,和数学一样,解题的方法绝 ...

  8. 2014年计算机一级考试操作题,2014国家计算机一级考试操作题常见题型.doc

    国家计算机一级B考试操作题常见题型 圩丰中学 刘华 一.基本操作 文件的复制 文件的移动 文件的删除 设置文件的属性 创制文件的快捷方式 方法:在找到的文件上右击[创建快捷方式] 文件或文件夹的改名 ...

  9. 一级b类计算机考试题目和类型,国家计算机一级B考试操作题常见题型

    国家计算机一级B考试操作题常见题型 圩丰中学刘华 一.基本操作 1.文件的复制 2.文件的移动 3.文件的删除 4.设置文件的属性 5.创制文件的快捷方式 方法:在找到的文件上右击[创建快捷方式] 6 ...

  10. 【Leetcode】完全背包问题-377. 组合总和 Ⅳ

    [Leetcode]完全背包问题-377. 组合总和 Ⅳ 题目 给你一个由 不同 整数组成的数组 nums ,和一个目标整数 target .请你从 nums 中找出并返回总和为 target 的元素 ...

最新文章

  1. LeetCode 873. 最长的斐波那契子序列的长度 题目详解
  2. 查看真实的执行计划 绑定变量对执行计划的影响--“绑定变量窥探”
  3. 【风控建模】互联网金融-机器学习及评分卡构建
  4. JS调用后台带参数的方法
  5. JavaScript实现唯一路径问题的回溯方法的算法(附完整源码)
  6. Java进阶之对象克隆(复制)
  7. java打印三角形,菱形。任意边长大小
  8. python构造数组并命名_Numpy数组追加命名列
  9. 财务总监的秘密:不用代码和Excel,10分钟做出高大上财务分析
  10. 反向题在测试问卷信效度_关于调查问卷的信度和效度检验
  11. redhat linux 无线网卡,RedHat Linux 6.4安装RTL8188CUS无线网卡驱动
  12. css hover变成手_html实现鼠标悬停变成手型实现方式
  13. 从敏思博客的倒闭事件看历史重现... 1
  14. client?0edb:161 [WDS] Errors while compiling. Reload prevented.
  15. 如何更改Code::Blocks背景颜色(懒人版)
  16. Excel COUNT COUNTA区别
  17. ionic类似时间轴的实现
  18. java ntlm解密_java – HttpClient 4.1.1在使用NTLM进行身份验证时返回401,浏览器工作正常...
  19. 【NPDP】大师级管理人物盘点:竞争战略之父-迈克尔·波特
  20. ajax请求返回的数据格式,ajax请求服务器返回json数据格式

热门文章

  1. 【网络通信 -- 直播】SRS 实战记录 -- 开源流媒体服务器对比与 SRS 直播效果测试
  2. 软件测试中单元测试的内容有哪些?-alltesting云测试
  3. cdr圆形渐变填充怎么设置_适用于平面设计的软件cdr!
  4. 数据统计分析(SPSS)【1】
  5. cce是什么意思_CCE 是什么
  6. 这应该是史上最强的物理学科普(雄文)
  7. 小米允许安装未知来源不用sim卡_视频能独立通话的小米手表,会像小米手机一样好用吗?...
  8. python判断工作日,节假日
  9. 02 敏捷开发测试流程
  10. 美国电话卡原生卡和虚商卡区别