热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Leetcode题解动态规划01背包(1):问题简介

0-1背包有一个容量为N的背包,要用这个背包装下物品的价值最大,这些物品有两个属性:体积w和价值v。定义一个二维数组dp存储最大价值&
0-1 背包

有一个容量为 N 的背包,要用这个背包装下物品的价值最大,这些物品有两个属性:体积 w 和价值 v。

定义一个二维数组 dp 存储最大价值,其中 dp[i][j] 表示前 i 件物品体积不超过 j 的情况下能达到的最大价值。设第 i 件物品体积为 w,价值为 v,根据第 i 件物品是否添加到背包中,可以分两种情况讨论:

  • 第 i 件物品没添加到背包,总体积不超过 j 的前 i 件物品的最大价值就是总体积不超过 j 的前 i-1 件物品的最大价值,dp[i][j] = dp[i-1][j]。
  • 第 i 件物品添加到背包中,dp[i][j] = dp[i-1][j-w] + v。

第 i 件物品可添加也可以不添加,取决于哪种情况下最大价值更大。因此,0-1 背包的状态转移方程为:

 

dp[i][j] = value dp[i - 1][j - w] + v;

public int knapsack(int W, int N, int[] weights, int[] values) {int[][] dp &#61; new int[N &#43; 1][W &#43; 1];for (int i &#61; 1; i <&#61; N; i&#43;&#43;) {int w &#61; weights[i - 1], v &#61; values[i - 1];for (int j &#61; 1; j <&#61; W; j&#43;&#43;) {if (j >&#61; w) {dp[i][j] &#61; Math.max(dp[i - 1][j], dp[i - 1][j - w] &#43; v);} else {dp[i][j] &#61; dp[i - 1][j];}}}return dp[N][W];
}

public int knapsack(int W, int N, int[] weights, int[] values){int[][] dp &#61; new int[N&#43;1][W&#43;1];for(int i&#61; 1; i<&#61;N; i&#43;&#43;){int w &#61; weights[i-1], v&#61; vlaues[i-1];for(int j&#61;1; j<&#61;W; j&#43;&#43;){if(j >&#61; w){dp[i][j] &#61; Math.max(dp[i-1][j], dp[i-1][j-w] &#43; v);elsedp[i][j] &#61; dp[i-1][j];}}}return dp[N][W];
}

空间优化

在程序实现时可以对 0-1 背包做优化。观察状态转移方程可以知道&#xff0c;前 i 件物品的状态仅与前 i-1 件物品的状态有关&#xff0c;因此可以将 dp 定义为一维数组&#xff0c;其中 dp[j] 既可以表示 dp[i-1][j] 也可以表示 dp[i][j]。此时&#xff0c;

 

因为 dp[j-w] 表示 dp[i-1][j-w]&#xff0c;因此不能先求 dp[i][j-w]&#xff0c;以防将 dp[i-1][j-w] 覆盖。也就是说要先计算 dp[i][j] 再计算 dp[i][j-w]&#xff0c;在程序实现时需要按倒序来循环求解。

public int knapsack(int W, int N, int[] weights, int[] values) {int[] dp &#61; new int[W &#43; 1];for (int i &#61; 1; i <&#61; N; i&#43;&#43;) {int w &#61; weights[i - 1], v &#61; values[i - 1];for (int j &#61; W; j >&#61; 1; j--) {if (j >&#61; w) {dp[j] &#61; Math.max(dp[j], dp[j - w] &#43; v);}}}return dp[W];
}

public int knapsack(int W, int N, int[] weights, int[] values){int[] dp &#61; new int[W&#43;1];for(int i&#61;1; i<&#61;N; i&#43;&#43;){int w &#61; weights[i-1], v&#61; values[i-1];for(int j&#61;W; j>&#61;1; j--){if(j >&#61; w)dp[j] &#61; Math.max(dp[j], dp[j-w] &#43; v);}}
}

无法使用贪心算法的解释

0-1 背包问题无法使用贪心算法来求解&#xff0c;也就是说不能按照先添加性价比最高的物品来达到最优&#xff0c;这是因为这种方式可能造成背包空间的浪费&#xff0c;从而无法达到最优。考虑下面的物品和一个容量为 5 的背包&#xff0c;如果先添加物品 0 再添加物品 1&#xff0c;那么只能存放的价值为 16&#xff0c;浪费了大小为 2 的空间。最优的方式是存放物品 1 和物品 2&#xff0c;价值为 22.

idwvv/w
0166
12105
23124

变种


  • 完全背包&#xff1a;物品数量为无限个

  • 多重背包&#xff1a;物品数量有限制

  • 多维费用背包&#xff1a;物品不仅有重量&#xff0c;还有体积&#xff0c;同时考虑这两种限制

  • 其它&#xff1a;物品之间相互约束或者依赖


推荐阅读
  • Java数组面试常见问题及解析
    在Java编程面试中,数组作为基础且重要的知识点,经常成为考察的重点。本文将探讨数组的基础知识和相关面试题,帮助考生更好地准备面试。 ... [详细]
  • 【Java数据结构和算法】008栈
    目录0、警醒自己一、栈的应用场景和介绍1、栈的应用场景一个实际的场景:我的思考:2、栈的介绍入栈演示图:出栈演示图 ... [详细]
  • 运用DDD分层架构优化微服务代码设计
    在微服务实施过程中,确定合理的代码结构至关重要。本文探讨了如何利用领域驱动设计(DDD)的分层架构来优化微服务的代码模型,确保系统的可维护性和扩展性。 ... [详细]
  • Lua基本语法lua与C#的交互(相当简单详细的例子)
    lua脚本与C#的交互本文提供全流程,中文翻译。Chinar坚持将简单的生活方式,带给世人!(拥有更好的阅读体验——高分辨率用户请根据需求调整网页缩放比例)1LuaAndC#——L ... [详细]
  • 峰值元素是指其数值高于其左右相邻元素的元素。本题要求在给定的无重复相邻元素的数组中找到一个峰值元素,并返回其索引。若数组存在多个峰值,则返回任意一个峰值的位置。 ... [详细]
  • 本文详细介绍了 Go 语言的关键特性和编程理念,包括其强大的并发处理能力、简洁的语法设计以及高效的开发效率。 ... [详细]
  • 本文详细介绍了快速排序算法的工作原理和实现步骤,包括选择基准值、分区过程以及递归调用等关键环节。通过具体的Java代码示例,帮助读者更好地理解和掌握这一高效的排序算法。 ... [详细]
  • 本文总结了几个常用的Android开发技巧,包括检测设备上是否安装特定应用、获取应用的版本名称、设置状态栏透明以及如何从一个应用跳转至另一个应用的方法。 ... [详细]
  • 本文详细介绍了MySQL表分区的概念、类型及其在实际应用中的实施方法,特别是针对Zabbix数据库的优化策略。 ... [详细]
  • 成为一名高效的Java架构师不仅需要掌握高级Java编程技巧,还需深入理解JVM的工作原理及其优化方法。此外,对池技术(包括对象池、连接池和线程池)的应用、多线程处理、集合对象的内部机制、以及常用的数据结构和算法的精通也是必不可少的。同时,熟悉Linux操作系统、TCP/IP协议栈、HTTP协议等基础知识,对于构建高效稳定的系统同样重要。 ... [详细]
  • 深入解析达内Java基础练习题
    本文精选了几道典型的Java基础题目,旨在帮助学习者巩固基础知识,提升编程技能。通过这些题目,你可以检验自己的Java基础掌握程度。 ... [详细]
  • Qt应用开发:创建基本窗口
    本文介绍如何使用Qt框架创建基础窗口的两种方法。第一种方法直接在main函数中创建并显示窗口;第二种方法通过定义一个继承自QWidget的类来实现更复杂的功能。 ... [详细]
  • 本文探讨了Lua中元表和元方法的使用,通过具体的代码示例展示了如何利用这些特性来实现类似C语言中的运算符重载功能。 ... [详细]
  • 本文介绍了一个基础算法题目,旨在通过求解特定范围内所有数字的阶乘之和来提升编程技能。重点在于理解和实现双重循环结构。 ... [详细]
  • 本章节深入讨论了线性光与感知均匀性的概念,强调了灰度图像中每个像素值如何反映视觉亮度的主观性质。文章进一步解析了亮度与光强度、辐射等物理量的区别,并探讨了这些概念在数字图像处理中的应用。 ... [详细]
author-avatar
风让我离开
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有