Leetcode 312. 戳气球(记忆化搜索)

news/2024/11/29 8:04:30/
  • Leetcode 312. 戳气球(记忆化搜索)
  • 题目
    • 有 n 个气球,编号为0 到 n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。
    • 现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。这里的 i - 1 和 i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1或 i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。
    • 求所能获得硬币的最大数量。
    • n == nums.length
    • 1 <= n <= 300
    • 0 <= nums[i] <= 100
  • 解法
    • 动态规划:设 val[i+1]=nums[i] 同时 val[0]=val[n+1]=1 头尾加 1 方便计算,然后定义 dp[i][j] 为戳破(i,j)开区间所有气球获得最多金币数量,n 个气球所能获得的最大金币就是 dp[0][n+1] 的值,接下来求转移方程式
    • 转移方程式:我们假设最后戳破的是第 k 个气球、同时 i<k<j,可得转移方程式:dp[i][j] = Max(dp[i][k] + val[i]*val[k]*val[j] + dp[k][j]),代表(i,k)与(k,j)已经被戳破了、再加上第 k 个气球的金币
    • 使用记忆化搜索的方式递归获取结果,出口条件是:当 i>=j-1 时 dp[i][j]=0
    • 时间复杂度:O(n^3)dp[0][n+1] 区间为 n^2、然后迭代 k 为 n 次,空间复杂度:O(n^2)
  • 代码
    /*** 动态规划:设 val[i+1]=nums[i] 同时 val[0]=val[n+1]=1 头尾加 1 方便计算,然后定义 dp[i][j] 为戳破(i,j)开区间所有气球获得最多金币数量,* n 个气球所能获得的最大金币就是 dp[0][n+1] 的值,接下来求转移方程式* 转移方程式:我们假设最后戳破的是第 k 个气球、同时 i<k<j,可得转移方程式:dp[i][j] = Max(dp[i][k] + val[i]*val[k]*val[j] + dp[k][j]),* 代表(i,k)与(k,j)已经被戳破了、再加上第 k 个气球的金币* 使用记忆化搜索的方式递归获取结果,出口条件是:当 i>=j-1 时 dp[i][j]=0* 时间复杂度:O(n^3)dp[0][n+1] 区间为 n^2、然后迭代 k 为 n 次,空间复杂度:O(n^2)*/private int solution(int[] nums) {// 判空if (nums == null || nums.length <= 0) {return 0;}// 设 val[i+1]=nums[i] 同时 val[0]=val[n+1]=1 头尾加 1 方便计算int[] val = getValByNums(nums);// valLen = n + 2int valLen = val.length;// System.out.println(Arrays.toString(val));// 记忆化搜索获取int[][] dp = new int[valLen][valLen];for (int i = 0; i < valLen; i++) {Arrays.fill(dp[i], -1);}recursionSearchDP(0, valLen-1, dp, val);return dp[0][valLen - 1];}/*** 记忆化搜索获取(left,right)获得的最大金币数*/private int recursionSearchDP(int left, int right, int[][] dp, int[] val) {if (left >= right - 1) {return 0;}if (dp[left][right] >= 0) {return dp[left][right];}// 循环最后一个戳破的气球for (int k = left + 1; k < right; k++) {dp[left][right] = Math.max(dp[left][right], recursionSearchDP(left, k, dp, val)+ recursionSearchDP(k, right, dp, val) + val[left]*val[k]*val[right]);}return dp[left][right];}/*** 获取 val 数组,设 val[i+1]=nums[i] 同时 val[0]=val[n+1]=1 头尾加 1 方便计算*/private int[] getValByNums(int[] nums) {int numLen = nums.length;int[] val = new int[numLen + 2];val[0] = 1;for (int i = 0; i < numLen; i++) {val[i+1] = nums[i];}val[val.length - 1] = 1;return val;}

http://www.ppmy.cn/news/198939.html

相关文章

汇编语言程序设计基础知识二

五、顺序结构 1、程序设计的步骤 1、分析问题 2、建立数据模型 3、设计算法 4、编制程序 5、上机调试 2、流程图的应用 3、程序的基本控制结构 1、顺序结构&#xff1a;程序顺序执行&#xff0c;不发生跳转 2、分支结构&#xff1a;程序在执行过程中发生跳转 3、循环…

FastBup:计算机视觉大型图像数据集分析工具

0.简介 官方github网址项目目的&#xff1a;当前大规模图像数据集一团糟&#xff0c;数据量巨大但质量堪忧&#xff0c;有时候训练集、验证集、测试集会有重复数据造成数据泄露。FastBup可以识别重复项、近似重复项、异常图像、错误标注、异常值&#xff0c;在cpu上就可以处理…

如何使用Java异常处理来优雅地处理各种异常情况?

在Java编程中&#xff0c;异常处理是一个非常重要的话题。良好的异常处理可以帮助我们更好地调试和排除代码中的错误&#xff0c;同时也可以提高代码的可读性、可维护性和稳定性。本文将详细介绍如何使用Java异常处理来优雅地处理各种异常情况。 异常分类 在Java中&#xff0…

web前端 --- BOM编程、DOM编程

BOM编程&#xff08;browser object model -- 浏览器对象模型&#xff09; BOM给JavaScript提供用来操作浏览器的若干的"方法" 操作 在 js 看来&#xff0c;一个完整的浏览器包含如下组件&#xff1a; window窗口 // 整个浏览器的窗口 |-- history …

戴尔7060安装win10系统教程

正常情况下用UltraISO制作启动盘&#xff0c;插入电脑&#xff0c;开机按下f12进行装机&#xff1b;但是戴尔7060发现找不到启动盘&#xff0c;解决办法uefi gui;如下&#xff1a; 1、制作U盘魔术师启动盘&#xff1a; 下载与制作参考连接&#xff1a; https://jingyan.baidu…

DAY780

如果我没记错的话&#xff0c;这应该是我在大学期间第二次发烧了&#xff0c;该怎么去形容这天气晴朗一天呢&#xff1f; 从早上到晚上&#xff0c;跑了四次医务室。去学校医务室的人看病的人只会多&#xff0c;不会少。第一次是早上九点多去的&#xff0c;那时候应该有四五个吧…

指纹图片调对比度 c语言,手动调整图片打印深浅(亮度/对比度 Windows OS)

文档标题&#xff1a;手动调整图片打印深浅(亮度/对比度 Windows OS) 文档代码&#xff1a;CHN-FP0548-1 最近修改日期&#xff1a;2020年11月19日 手动调整图片打印深浅(亮度/对比度 Windows OS) 说明&#xff1a; 通过打印机驱动设置图形打印的亮度和对比度&#xff0c;就可以…

linux卸载驱动命令,卸载打印机驱动程序 (Linux)

相关型号 ADS-1100W, ADS-1200, ADS-1600W, ADS-1700W, ADS-2100, ADS-2200, ADS-2600W, ADS-2700W, DCP-110C, DCP-115C, DCP-120C, DCP-130C, DCP-145C, DCP-1518, DCP-1519, DCP-155C, DCP-1608, DCP-1618W, DCP-1619, DCP-165C, DCP-185C, DCP-330C, DCP-350C, DCP-385C, D…