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

dp背包问题——1049.最后一块石头的重量II

本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。和416.分割等和子集非常像,只需要使用石

在这里插入图片描述

本题其实就是尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,这样就化解成01背包问题了。

和416. 分割等和子集非常像,只需要使用石头总重量的一半作为背包容量,通过01背包的dp算法,计算出一半容量所能装入的最大石头重量,就能使得最后剩余的石头最小

本题物品的重量为stones[i],物品的价值也为stones[i]

先写出常见的二维数组解法:

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {if(stones.size() &#61;&#61; 1){return stones[0];}int n &#61; stones.size();int sum &#61; accumulate(stones.begin(), stones.end(), 0);int content &#61; sum / 2;vector<vector<int>> dp(n, vector<int>(content &#43; 1, 0)); // 由于j是容量&#xff0c;不仅是下标&#xff0c;还有实际意义&#xff0c;需要content&#43;1for(int j &#61; 1; j <&#61; content; j&#43;&#43;){dp[0][j] &#61; j >&#61; stones[0] ? stones[0] : 0;}// 先遍历物品&#xff0c;再遍历容量for(int i &#61; 1; i < n; i&#43;&#43;){for(int j &#61; 1; j <&#61; content; j&#43;&#43;){if(j < stones[i]){// 当前背包容量 <物品重量dp[i][j] &#61; dp[i-1][j];}else{dp[i][j] &#61; max(dp[i-1][j], dp[i-1][j-stones[i]] &#43; stones[i]);}}}return sum - 2 * dp[n-1][content];}
};

通过滚动数组优化&#xff0c;尤其需要注意&#xff1a;

  1. 为什么需要从后往前遍历容量
  2. 为什么遍历容量时&#xff0c;没有显式判断当前容量j小于当前物品重量nums[i]

class Solution {
public:int lastStoneWeightII(vector<int>& stones) {if(stones.size() &#61;&#61; 1){return stones[0];}int n &#61; stones.size();int sum &#61; accumulate(stones.begin(), stones.end(), 0);int content &#61; sum / 2;// vector> dp(n, vector(content &#43; 1, 0)); // 由于j是容量&#xff0c;不仅是下标&#xff0c;还有实际意义&#xff0c;需要content&#43;1vector<int> dp(content &#43; 1, 0);// 用第一个物品初始化dp数组for(int j &#61; 1; j <&#61; content; j&#43;&#43;){dp[j] &#61; j >&#61; stones[0] ? stones[0] : 0;}// 先遍历物品&#xff0c;再遍历容量for(int i &#61; 1; i < n; i&#43;&#43;){// 滚动数组&#xff0c;从后往前遍历容量for(int j &#61; content; j >&#61; stones[i]; j--){dp[j] &#61; max(dp[j], dp[j-stones[i]] &#43; stones[i]);}}return sum - 2 * dp[content];}
};


推荐阅读
  • 贡献转移在计算每个元素的作用的时候,我们可以通过反向枚举作用效果,添加到作用元素的身上,这种方法叫做贡献转移。更正式的说, ... [详细]
  • 使用Matlab创建动态GIF动画
    动态GIF图可以有效增强数据表达的直观性和吸引力。本文将详细介绍如何利用Matlab软件生成动态GIF图,涵盖基本代码实现与高级应用技巧。 ... [详细]
  • 本文将探讨一个经典算法问题——最大连续子数组和。我们将从问题定义出发,逐步深入理解其背后的逻辑,并通过实例分析加深理解。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 1、编写一个Java程序在屏幕上输出“你好!”。programmenameHelloworld.javapublicclassHelloworld{publicst ... [详细]
  • 视觉Transformer综述
    本文综述了视觉Transformer在计算机视觉领域的应用,从原始Transformer出发,详细介绍了其在图像分类、目标检测和图像分割等任务中的最新进展。文章不仅涵盖了基础的Transformer架构,还深入探讨了各类增强版Transformer模型的设计思路和技术细节。 ... [详细]
  • 深入解析 C++ 中的 String 和 Vector
    本文详细介绍了 C++ 编程语言中 String 和 Vector 的使用方法及特性,旨在帮助开发者更好地理解和应用这两个重要的容器。 ... [详细]
  • 本文详细介绍了在Luat OS中如何实现C与Lua的混合编程,包括在C环境中运行Lua脚本、封装可被Lua调用的C语言库,以及C与Lua之间的数据交互方法。 ... [详细]
  • 想把一组chara[4096]的数组拷贝到shortb[6][256]中,尝试过用循环移位的方式,还用中间变量shortc[2048]的方式。得出的结论:1.移位方式效率最低2. ... [详细]
  • 本文深入探讨了动态赋值的概念及其在编程实践中的应用,特别是通过Java代码示例来展示如何利用循环结构动态地为数组分配值。 ... [详细]
  • 本文提供了一种有效的方法来解决当Android Studio因电脑意外重启而导致的所有import语句出现错误的问题。通过清除缓存和重建项目结构,可以快速恢复开发环境。 ... [详细]
  • 网络流24题——试题库问题
    题目描述:假设一个试题库中有n道试题。每道试题都标明了所属类别。同一道题可能有多个类别属性。现要从题库中抽取m道题组成试卷。并要求试卷包含指定类型的试题。试设计一个满足要求的组卷算 ... [详细]
  • 本文详细探讨了在Java中如何将图像对象转换为文件和字节数组(Byte[])的技术。虽然网络上存在大量相关资料,但实际操作时仍需注意细节。本文通过使用JMSL 4.0库中的图表对象作为示例,提供了一种实用的方法。 ... [详细]
  • 函子(Functor)是函数式编程中的一个重要概念,它不仅是一个特殊的容器,还提供了一种优雅的方式来处理值和函数。本文将详细介绍函子的基本概念及其在函数式编程中的应用,包括如何通过函子控制副作用、处理异常以及进行异步操作。 ... [详细]
  • 本文介绍了多维缩放(MDS)技术,这是一种将高维数据映射到低维空间的方法,通过保持原始数据间的关系,以便于可视化和分析。文章详细描述了MDS的原理和实现过程,并提供了Python代码示例。 ... [详细]
author-avatar
sunshinechenxm
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有