动态规划之二维数组系列——01背包,不同的子序列

2023-11-06

01背包问题

题目描述
小明有一个容量为 V 的背包。
这天他去商场购物,商场一共有 N 件物品,第 i 件物品的体积为 wi,价值为 vi。
小明想知道在购买的物品总体积不超过 V 的情况下所能获得的最大价值为多少。

解题思路
现假设 V 为 7,N 为 4,他们的 w 分别为 1,3,4,5 。v 分别为1,4,5,7。
要想解决这个问题可以先建立一个 N 行 V 列的二位数组,即解决此问题的dp数组,值为此时背包可装下物品的最大价值。

解题过程
当背包容积为0时,无法装下任意体积的商品,故第一列全为零,即最大价值为0。
现在我们逐行进行遍历:

(1)当背包容积为1时,我们发现刚好可以装下第一个物品(体积为1),此时背包可装物品的最大价值为1,第一行都是这种情况。
(2)第二行,当背包容量为1,2时,不能选择装入第一个物品(因为w2=3大于此时背包容量),故此时能装入的最大价值和上一行一样,即dp[i][j]=dp[i-1][j]。
(3)当体积为3时,此时是可以装下第二个物品的,但是要分两种情况讨论:1.装第二个物品;2.不装第二个物品。
情况1:装下第二个物品后,背包剩余体积为 j-w[2]=0,此时不能再装下其他物品了,故该情况的最大价值为4。
情况2:不装第二个物品,此时的最大价值和上一行一样,即dp[i][j]=dp[i-1][j],即为1.

总结:通过比较两种情况发现,情况1的价值(val=4)比情况2的价值(val=1)大,所以这里选择装第二件物品,转化为dp公式就是:dp[i][j]=max(dp[i-1][j],dp[i][j-w[i]]+val[i])。
(到这里可能就有小伙伴不理解 dp[i][j-w[i]]+val[i] 了,别急!听我细细道来!)

显而易见,dp[i][j-w[i]]+val[i]中的 +val[i] 部分就是刚刚的情况2,那为什么要有前面的 dp[i][j-w[i]] 呢?
刚刚情况2直接得出最大价值val[2]是4,没有 dp[i][j-w[i]] 是因为装下第二件物品后背包的剩余容易为零了。我们再看刚刚的dp[i][j-w[i]] 不就是dp[2][0]=0吗?所以刚刚情况2的完整写法应该是最大价值是0+4=4。

在这里插入图片描述
关键代码

for (int i = 1; i <= n; i++) {
   	for (int j = 1; j <=v; j++) {
        if(wei[i]>j) {
            dp[i][j]=dp[i-1][j];
        }else {
            dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-wei[i]]+val[i]);
        }
    }
}

完整代码

import java.util.Scanner;

public class Main {
    
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int v=sc.nextInt();
        int[][] dp=new int[n+1][v+1];
        int[] val=new int[n+1];
        int[] wei=new int[n+1];
        for (int i = 1; i < n+1; i++) {
            wei[i]=sc.nextInt();
            val[i]=sc.nextInt();
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <=v; j++) {
                if(wei[i]>j) {
                    dp[i][j]=dp[i-1][j];
                }else {
                    dp[i][j]=Math.max(dp[i-1][j],dp[i-1][j-wei[i]]+val[i]);
                }
            }
        }
        System.out.println(dp[n][v]);
    }
}

相关练习
蓝桥杯练习——小明的背包1
力扣——115.不同的子序列

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

动态规划之二维数组系列——01背包,不同的子序列 的相关文章

  • 模糊匹配之——BK树与拼写纠正

    介绍 拼写纠错功能常常出现在比较高级的文本编辑应用中 例如大家熟知的word 高级一点的IDE例如Jet Brains系列 在一些在线翻译上 也有自动校正拼写的功能 例如谷歌翻译 原理 拼写纠正的实现方式有多种 这里使用的是一种名为BK树的
  • Python实现找零兑换的三种解法

    找零兑换 找零兑换问题最直接的解法就是贪心策略 比如问题 有面值1 5 10 25的硬币 求解兑换63元所需的最少硬币数 贪心策略的思想就是不断的利用面值最大的硬币去尝试 不行了 在尝试较小面值的硬币 该例中也即使用25的硬币去尝试 2枚2
  • 基于Dijkstra、A*和动态规划的移动机器人路径规划(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 目录 1 概述 2 运行结果 2 1 Dijkstra算法 2 2 A 算法 2 3 动态规划 3 Matlab代码实现 1 概述 在基
  • 蓝桥杯接龙数列(动态规划)

    蓝桥杯2023年第十四届省赛真题 接龙数列 C语言网 dotcpp com 我们要求最少删除多少个数 可以使剩下的序列是接龙序列 那么找到一条最长的接龙数列即可求出最少删除的个数 运用动态规划的思想 从前往后挨个考虑每个数字 一个前缀为6的
  • LeetCode312. 戳气球 (分治,记忆化搜索,动态规划)

    LeetCode312 戳气球 解题思路 记忆化搜索 动态规划 解题思路 官方题解 参考题解 核心思想 由于戳气球的操作会导致两个气球从不相邻变成相邻 使得后续操作难以处理 于是我们倒过来看这些操作 将全过程看成每次添加一个气球 solve
  • 数字三角形之动态规划(C语言实现)

    算法步骤 1 首先构造三个数组 第一个是存储三角形初始值的数组data 第二个是存储顶点到该点最大值的res 数组 第三个是存储该点上一个点的loc 数组 这里要对res 数组进行初始化 1 2 按照三角形的层次结构 从上到下 从左到右依次
  • 华为od机考题目-HJ68-成绩排序(比较难)

    while 1 try count int input reverse True if input 0 else False temp lt
  • 试除法判定质数模板题

    试除法判定一个数是否为质数类似于这道题 代码 include
  • 备战2023蓝桥国赛-传纸条

    题目描述 解析 这道题想了我好久 一开始我是想假如只走一条路线 从 1 1 走到 m n 这种问题该怎么解决呢 针对这种问题我是设了dp k i j 表示走了k步到达 i j 的好心程度之和的最大值 然后根据这个来写出转移方程来计算 后面就
  • [leetcode] 推多米诺 双指针

    题目链接 一开始想多了 像成了真实生活中的那种会叠加的状态 就比如 RRL 中 左边的两个 R 会让第三个 L 向右边倾斜 直接用前缀和进行操作 但是发现示例1都无法通过 所以说是错的 正确的想法是 每一个暂未确定状态的 都由这个字符两侧最
  • 动态规划算法解决背包问题(Java实现)

    文章收藏的好句子 你在书本上花的任何时间 都会在某一个时刻给你回报 目录 1 动态规划算法的概述 2 背包问题 3 动态规划算法解决背包问题 3 1 不可重复装入商品 3 2 思路分析 1 动态规划算法的概述 1 动态规划算法的思想是 将大
  • ARC105

    C Camels and Bridge 题意 一堆骆驼过桥 每个桥有承重和长度 问骆驼从头到尾的最近距离 假设这时候骆驼的过桥顺序已经安排好 每一个桥相当于一个限制条件 限制了 l r 的最近距离 也就是说 对于每一个骆驼 j 要保证 好了
  • leetcode刷题(77)——312. 戳气球

    一 题目 有 n 个气球 编号为0 到 n 1 每个气球上都标有一个数字 这些数字存在数组 nums 中 现在要求你戳破所有的气球 每当你戳破一个气球 i 时 你可以获得 nums left nums i nums right 个硬币 这里
  • 华为od机考真题-HJ17坐标移动(中等)

    data input l r 0 0 for ad in data split ad
  • OJ刷题---【算法课动态规划] 换硬币(C++完整代码)

    题目 给定面值分别为2 5 7的硬币 每种硬币有无限个 给定一个N 求组成N最少需要的硬币的数量 若无法组成则返回 1 输入 输入N 1 lt N lt 100 输出 输出需要的最少硬币个数 完整代码 C include
  • HJ103 Redraiment的走法

    Redraiment是走梅花桩的高手 Redraiment可以选择任意一个起点 从前到后 但只能从低处往高处的桩子走 他希望走的步数最多 你能替Redraiment研究他最多走的步数吗 示例 2 5 1 5 4 5 输出 3 说明 6个点的
  • 2023华为OD机试真题【星际篮球争霸赛/动态规划】

    题目描述 在星球争霸篮球赛对抗赛中 最大的宇宙战队希望每个人都能拿到MVP MVP的条件是单场最高分得分获得者 可以并列所以宇宙战队决定在比赛中尽可能让更多队员上场 并且让所有得分的选手得分都相同 然而比赛过程中的每1分钟的得分都只能由某一
  • 【LeetCode75】第五十九题 第N个泰波那契数

    目录 题目 示例 分析 代码 题目 示例 分析 题目顾名思义 让我们求出第N个泰波那契数 也就是除了开头三个数之外 第四个数开始就是等于前三个数之和 不要和斐波那契数弄混了 斐波那契是前两个数的和 泰波那契是前三个数的和 也就是说当前数 我
  • 最大k乘积问题--动态规划

    问题 问题描述 设x是一个n位十进制整数 如果将x划分为k段 则可得到k个整数 这k个整数的乘积称为x的一个k乘积 试设计一个算法 对于给定的x和k 求出x的最大k乘积 编程任务 对于给定的x和k 编程计算x的最大k 乘积 示例 Sampl
  • 雪糕的最大数量 排序+贪心

    雪糕的最大数量 雪糕的最大数量 题目描述 样例 数据范围 思路 代码 题目描述 夏日炎炎 小男孩 Tony 想买一些雪糕消消暑 商店中新到 n 支雪糕 用长度为 n 的数组 costs 表示雪糕的定价 其中 costs i 表示第 i 支雪

随机推荐