312. 戳气球

题目

n 个气球,编号为 0n - 1,每个气球上都标有一个数字,这些数字存在数组 nums 中。

现在要求你戳破所有的气球。戳破第 i 个气球,你可以获得 nums[i - 1] * nums[i] * nums[i + 1] 枚硬币。 这里的 i - 1i + 1 代表和 i 相邻的两个气球的序号。如果 i - 1i + 1 超出了数组的边界,那么就当它是一个数字为 1 的气球。

求所能获得硬币的最大数量。

示例 1:

输入:nums = [3,1,5,8]
输出:167
解释:

nums = [3,1,5,8] --> [3,5,8] --> [3,8] --> [8] --> []
coins =  3*1*5    +   3*5*8   +  1*3*8  + 1*8*1 = 167

示例 2:

输入:nums = [1,5]
输出:10

提示:

  • n == nums.length
  • 1 <= n <= 300
  • 0 <= nums[i] <= 100

代码

完整代码

#include <stdio.h>
#include <stdlib.h>#define MAX(a,b) ((a) > (b) ? (a) : (b))typedef struct {int val;int oldindex;
} st_t;int cmp(const void *a, const void *b) {return (*(st_t*)b).val - (*(st_t*)a).val;
}int calcscore(int* arr, int thisInputIndex, int thisInputVal, int numsSize) {int beforevalue = 1;int aftervalue = 1;// Find the first non -1 value on the rightfor (int i = thisInputIndex + 1; i < numsSize; i++) {if (arr[i] != -1) {aftervalue = arr[i];break;}}// Find the first non -1 value on the leftfor (int i = thisInputIndex - 1; i >= 0; i--) {if (arr[i] != -1) {beforevalue = arr[i];break;}}arr[thisInputIndex] = thisInputVal;return thisInputVal * beforevalue * aftervalue;
}void dfs(int* arr, int* nums, int numsSize, int* score, int* highestScore) {int found = 0;for (int i = 0; i < numsSize; i++) {if (arr[i] == -1) {found = 1;int nowscore = calcscore(arr, i, nums[i], numsSize);*score += nowscore;dfs(arr, nums, numsSize, score, highestScore);*score -= nowscore;arr[i] = -1; // Reset the position after recursion}}if (!found && *score > *highestScore) {*highestScore = *score;}
}int maxCoins(int* nums, int numsSize) {int score = 0;int highestScore = 0;int* arr = (int*)malloc(numsSize * sizeof(int));for (int i = 0; i < numsSize; i++) {arr[i] = -1; // 初始化为-1,表示该位置还没有填入数字}dfs(arr, nums, numsSize, &score, &highestScore);free(arr);return highestScore;
}

思路分析

  1. 回溯算法:通过深度优先搜索(DFS)来枚举所有可能的戳气球顺序,计算每种顺序下能获得的最大硬币数量。
  2. 计算分数:定义 calcscore 函数来计算戳破当前气球时可以获得的硬币数,考虑到边界条件处理。
  3. 记录最高分:在 DFS 过程中记录获得的最高硬币数。

拆解分析

  • 回溯搜索:遍历数组,每次选取一个未被戳破的气球进行递归处理。
  • 分数计算:计算每次戳破气球后的硬币数,并在递归返回时进行回溯。
  • 结束条件:当所有气球都被戳破时,更新最高硬币数。

复杂度分析

  • 时间复杂度O(n!),其中 n 是数组 nums 的长度。每次递归都要对剩余未戳破的气球进行选择,因此是一个阶乘级别的复杂度。
  • 空间复杂度O(n),递归栈的深度最大为数组 nums 的长度。

结果

在这里插入图片描述

一题多解

动态规划

动态规划思路分析

  1. 定义状态:使用二维数组 dp,其中 dp[i][j] 表示戳破 nums[i...j] 区间内所有气球可以获得的最大硬币数量。
  2. 状态转移:枚举区间内所有可能的最后一个被戳破的气球 k,计算戳破 k 号气球后的分数贡献,并加上 k 两侧已戳破气球的最大分数贡献。
  3. 初始化:所有单个气球戳破后获得的硬币数是 nums[i-1] * nums[i] * nums[i+1]
  4. 结果记录dp[0][n-1] 即为所求的最大硬币数。

动态规划拆解分析

最重要的就是这个三重循环:

    for (int length = 2; length < n; length++) {for (int left = 0, right = left + length; left < n - length; left++) {for (int i = left + 1; i < right; i++) {dp[left][right] = MAX(dp[left][right], newNums[left] * newNums[i] * newNums[right] + dp[left][i] + dp[i][right]);}}}
  • 第一层:for (int length = 2; length < n; length++)
    作用为控制区间长度,因为最终我们需要获得从0 ~ numsSize这个区间的最大值,因此我们需要依次获取长度为 numsSize, numsSize -1, ……, 2,之所以从2开始是因为如果len = 1,不用算,score就是nums[i];
  • 第二层for (int left = 0, right = left + length; left < n - length; left++)
    控制左右边界,从0开始依次扫描一遍各个可能的区间,计算每个可能的区间的得分。
  • 第三层for (int i = left + 1; i < right; i++)
    在区间内戳破每个气球,看看这个区间内戳破哪个气球使得总得分最高,其中,dp[left][i] dp[i][right]是戳破从左到i和从i到右的所有气球的分数,这样就保证了第三层循环内戳破第i个气球时,所有其他气球都被戳破并积分。

动态规划复杂度分析

  • 时间复杂度O(n^3),三重循环枚举所有可能的区间和最后一个戳破的气球。
  • 空间复杂度O(n^2),使用二维数组存储 dp 值。

动态规划代码

#include <stdio.h>
#include <stdlib.h>
#define MAX(a,b) ((a) > (b) ? (a) : (b))int maxCoins(int* nums, int numsSize) {int n = numsSize + 2;int* newNums = (int*)malloc(n * sizeof(int));newNums[0] = newNums[n - 1] = 1;for (int i = 0; i < numsSize; i++) {newNums[i + 1] = nums[i];}int** dp = (int**)malloc(n * sizeof(int*));for (int i = 0; i < n; i++) {dp[i] = (int*)calloc(n, sizeof(int));}for (int length = 2; length < n; length++) {for (int left = 0, right = left + length; left < n - length; left++) {for (int i = left + 1; i < right; i++) {dp[left][right] = MAX(dp[left][right], newNums[left] * newNums[i] * newNums[right] + dp[left][i] + dp[i][right]);}}}int result = dp[0][n - 1];for (int i = 0; i < n; i++) {free(dp[i]);}free(dp);free(newNums);return result;
}

结果

在这里插入图片描述

总结

dp相比于dfs暴力枚举所有情况,会大量使用之前得到的值来起到剪枝的效果,对于现在大家不缺空间来说肯定是dp更优,但是如果用在小型嵌入式系统,ram不够的话,dfs+剪枝也是一种可以考虑的方法。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/345253.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TCP/IP协议介绍——三次握手四次挥手

TCP/IP&#xff08;Transmission Control Protocol/Internet Protocol&#xff0c;传输控制协议/网际协议&#xff09;是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议&#xff0c;而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议…

Elastic Search 8.14:更快且更具成本效益的向量搜索,使用 retrievers 和重新排序提升相关性,RAG 和开发工具

作者&#xff1a;来自 Elastic Yaru Lin, Ranjana Devaji 我们致力于突破搜索开发的界限&#xff0c;并专注于为搜索构建者提供强大的工具。通过我们的最新更新&#xff0c;Elastic 对于处理以向量表示的大量数据的客户来说变得更加强大。这些增强功能保证了更快的速度、降低的…

SpringFramework总结

一.SpringFramework介绍 (一)Spring 广义上的 Spring 泛指以 Spring Framework 为基础的 Spring 技术栈。 Spring 已经不再是一个单纯的应用框架&#xff0c;而是逐渐发展成为一个由多个不同子项目&#xff08;模块&#xff09;组成的成熟技术&#xff0c;例如 Spring Frame…

一分钟有60秒,这个有趣的原因你知道吗?

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

AI图书推荐:这就是ChatGPT

这本书《这就是ChatGPT》&#xff08;What Is ChatGPT Doing ... and Why Does It Work &#xff09;由Stephen Wolfram撰写 全书内容概要如下&#xff1a; **引言与预备知识** - 作者首先表达了对ChatGPT技术突破的兴奋之情&#xff0c;指出这不仅是技术的故事&#xff0c;也是…

Go select 语句使用场景

1. select介绍 select 是 Go 语言中的一种控制结构&#xff0c;用于在多个通信操作中选择一个可执行的操作。它可以协调多个 channel 的读写操作&#xff0c;使得我们能够在多个 channel 中进行非阻塞的数据传输、同步和控制。 基本语法&#xff1a; select {case communica…

单灯双控开关原理

什么是单灯双控&#xff1f;顾名思义&#xff0c;指的是一个灯具可以通过两个不同的开关或控制器进行控制。 例如客厅的主灯可能会设置成单灯双控&#xff0c;一个开关位于门口&#xff0c;另一个位于房间内的另一侧&#xff0c;这样无论你是从门口进入还是从房间内出来&#x…

多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政线下预约等多场景应用支持H5+小程序+APP

多客陪玩系统-开源陪玩系统平台源码-支持游戏线上陪玩家政按摩线下预约等多场景应用支持H5小程序APP 软件架构 前端&#xff1a;Uniapp-vue2.0 后端&#xff1a;Thinkphp6 前后端分离 前端支持&#xff1a; H5小程序双端APP&#xff08;安卓苹果&#xff09; 安装教程 【商业…

6月7号作业

1&#xff0c; 搭建一个货币的场景&#xff0c;创建一个名为 RMB 的类&#xff0c;该类具有整型私有成员变量 yuan&#xff08;元&#xff09;、jiao&#xff08;角&#xff09;和 fen&#xff08;分&#xff09;&#xff0c;并且具有以下功能&#xff1a; (1)重载算术运算符…

使用 GPT-4 创作高考作文 2024年

使用 GPT-4 创作高考作文 2024年 使用 GPT-4 创作高考作文&#xff1a;技术博客指南 &#x1f914;✨摘要引言正文内容&#xff08;详细介绍&#xff09; &#x1f4da;&#x1f4a1;什么是 GPT-4&#xff1f;高考作文题目分析 ✍️&#x1f9d0;新课标I卷 人类智慧的进步&…

什么是pump?pump跟单机器人是什么?

区块链pump&#xff08;拉盘&#xff09;是一种市场操纵策略&#xff0c;通常指在短时间内人为抬高某种加密货币的价格&#xff0c;从而吸引其他投资者购买&#xff0c;随后通过快速出售&#xff08;dump&#xff09;获利。这种策略通常由一群协调好的投资者或交易团体执行&…

HikariCP连接池初识

HikariCP的简单介绍 hikari-光&#xff0c;hikariCP取义&#xff1a;像光一样轻和快的Connetion Pool。这个几乎只用java写的中间件连接池&#xff0c;极其轻量并注重性能&#xff0c;HikariCP目前已是SpringBoot默认的连接池&#xff0c;伴随着SpringBoot和微服务的普及&…

【WP|9】深入解析WordPress [add_shortcode]函数

add_shortcode 是 WordPress 中一个非常强大的函数&#xff0c;用于创建自定义的短代码&#xff08;shortcodes&#xff09;。短代码是一种简洁的方式&#xff0c;允许用户在内容中插入动态的、可重用的功能。通过 add_shortcode&#xff0c;开发者可以定义自己的短代码&#x…

Linux基础指令(一)

前言 Linux基础指令主要学习&#xff1a;对目录、文件、压缩包、匹配查找&#xff0c;权限等操作 第一次接触ubuntu需要知道的基本知识 sudo passwd root 先给root用户设置密码 su root 切换到root用户 su zhangsan …

Sui Generis如何为艺术家弥合Web3的鸿沟

Sui Generis是一家于3月推出的NFT拍卖行&#xff0c;其联合创始人兼CEO Gab9说其愿景是——更好、更大、更强&#xff01; 表面上看&#xff0c;Sui Generis是备受欢迎的Tombheads NFT拍卖行的重新品牌化&#xff0c;该拍卖行今年早些时候从Fantom区块链迁移出来。但它于3月31…

音视频开发19 FFmpeg 视频解码- 将 h264 转化成 yuv

视频解码过程 视频解码过程如下图所示&#xff1a; ⼀般解出来的是420p FFmpeg流程 这里的流程是和音频的解码过程一样的&#xff0c;不同的只有在存储YUV数据的时候的形式 存储YUV 数据 如果知道YUV 数据的格式 前提&#xff1a;这里我们打开的h264文件&#xff0c;默认是YU…

搜索与图论:宽度优先搜索

搜索与图论&#xff1a;宽度优先搜索 题目描述参考代码 题目描述 输入样例 5 5 0 1 0 0 0 0 1 0 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0输出样例 8参考代码 #include <iostream> #include <algorithm> #include <cstring> using namespace std;const int N …

course-nlp——8-translation-transformer

本文参考自https://github.com/fastai/course-nlp。 注意力机制和 Transformer Nvidia AI 研究员 Chip Huyen 写了一篇很棒的文章《Top 8 trends from ICLR 2019》&#xff0c;其中的趋势之一是 RNN 正在失去研究人员的青睐。 这是有原因的&#xff0c;RNN 可能很麻烦&#…

course-nlp——5-nn-imdb

本文参考自https://github.com/fastai/course-nlp。这部分是fastai1.0版本的教程&#xff0c;由于现在fastai2.0重构的改变非常大&#xff0c;所以文中的很多api都变了&#xff0c;由于学习目的并不是熟练掌握fastai&#xff0c;因此这里就简单的存一下&#xff0c;本文是用IMD…

数据库 | 关系数据库设计

第七章 1.简述数据库的设计阶段&#xff1f;&#xff08;简要回答数据库设计步骤&#xff1f;&#xff09;&#xff08;&#xff08;数据库设计有哪几个阶段&#xff1f;&#xff09; 需求分析、概念结构设计、逻辑结构设计、物理结构设计、数据库的实施、数据库的运行和维护…