LintCode 吹气球

2024-09-02 17:08
文章标签 气球 lintcode

本文主要是介绍LintCode 吹气球,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

有n个气球,编号为0到n-1,每个气球都有一个分数,存在nums数组中。每次吹气球i可以得到的分数为 nums[left] * nums[i] * nums[right],left和right分别表示i气球相邻的两个气球。当i气球被吹爆后,其左右两气球即为相邻。要求吹爆所有气球,得到最多的分数。

样例
给出 [4, 1, 5, 10]
返回 270

nums = [4, 1, 5, 10] burst 1, 得分 4 * 1 * 5 = 20
nums = [4, 5, 10] burst 5, 得分 4 * 5 * 10 = 200
nums = [4, 10] burst 4, 得分 1 * 4 * 10 = 40
nums = [10] burst 10, 得分 1 * 10 * 1 = 10
总共的分数为 20 + 200 + 40 + 10 = 270

动态规划。
首先按照题意,我们可以先在nums数组两端各加一个1,方便计算。
dp[i , j]表示吹爆第i个到第j个气球能获得的最多的分数。对于第i 到 第j个气球中,可以首先吹爆任意一个气球k(i<=k<=j),吹爆第k个气球时,能获得的分数为nums[k]* (此刻k的前一个数)* (此刻k的后一个数),但是由于并不知道之前k左边和右边的气球有没有被吹爆,所以不能确定此刻左右的数。换一种思路,既然可以首先吹爆任意一个气球k,那么也可以选择最后吹爆任意一个气球k。此时,k的左右数字就确定了,分别是nums[i-1]和nums[j+1]。

那么获得的分数就是nums[i-1]* nums[k]* nums[j+1],这是吹爆k获得的分数,再加上吹爆k之前获得的最大分数dp[i , k-1]+dp[k+1 , j](即在k之前吹爆的:k左边第i个到第k-1个,k右边第k+1个到第j个)。综上,dp[i , j]=max(nums[i-1]* nums[k]* nums[j+1] + dp[i , k-1]+ dp[k+1 , j]),(对于所有的 k : i<=k<=j).

显然,求dp[i , j]时,需要dp[i , k-1] , dp[k+1 , j],即区间长度小于i到j的区间长度的dp。所以可以从区间长度为1开始求解。这个和算法导论上动态规划那一章的矩阵链乘法类似,LintCode上另外一道题 Guess Number Game II也是这种按区间长度的增长来求解。

最后的结果为 dp[1 , n]。
代码如下:

class Solution(object):"""@param {int[]} nums a list of integer@return {int} an integer, maximum coins"""def maxCoins(self, nums):# Write your code heren=len(nums)nums.append(1)nums.insert(0,1)dp=[[0 for x in range(n+2)] for y in range(n+2)]for length in range(1,n+1):for i in range(1,n-length+2):j=i+length-1q=0for k in range(i,j+1):q=nums[i-1]*nums[k]*nums[j+1]+dp[i][k-1]+dp[k+1][j]if q>dp[i][j]:dp[i][j]=qreturn dp[1][n]

这篇关于LintCode 吹气球的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1130550

相关文章

LintCode 恢复IP地址

给一个由数字组成的字符串。求出其可能恢复为的所有IP地址。 样例 给出字符串 “25525511135”,所有可能的IP地址为: [ “255.255.11.135”, “255.255.111.35” ] 和LintCode 电话号码的字母组合类似。 首先找到合适的位数组合。一共4位,每一位的长度要大于等于1,小于等于3,且4位和为字符串长度. 另外要判断每1 位的数字组合,是

LintCode 最长无重复字符的子串

给定一个字符串,请找出其中无重复字符的最长子字符串。 例如,在”abcabcbb”中,其无重复字符的最长子字符串是”abc”,其长度为 3。 对于,”bbbbb”,其无重复字符的最长子字符串为”b”,长度为1。 从左向右扫描,遇到重复的字符时,从前面出现该字符的位置的下一个字符开始,重新扫描,直到扫描到最后。例如: abcbdefgdk 字符abcbdefgdk下标0123456789

LintCode 最长回文子串

给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串。 样例 给出字符串 “abcdzdcab”,它的最长回文子串为 “cdzdc”。 挑战 O(n2) 时间复杂度的算法是可以接受的,如果你能用 O(n) 的算法那自然更好。 第一次AC的连O(n2)都不是的,是O(n3),遍历所有子串。代码如下: class Solution:"""@

LintCode 电话号码的字母组合

Given a digit string excluded 01, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. 样例 给定 “

LintCode 通配符匹配

参考资料 判断两个可能包含通配符“?”和“*”的字符串是否匹配。匹配规则如下: ‘?’ 可以匹配任何单个字符。 ‘*’ 可以匹配任意字符串(包括空字符串)。 两个串完全匹配才算匹配成功。 函数接口如下: bool isMatch(const char *s, const char *p) 一些例子: isMatch(“aa”,”a”) → false isMatch(“aa”,”

LintCode 落单的数 ⅡⅢ

参考资料 落单的数Ⅱ 给出3*n + 1 个的数字,除其中一个数字之外其他每个数字均出现三次,找到这个数字。 样例 给出 [1,1,2,3,3,3,2,2,4,1] ,返回 4 落单的数Ⅲ 给出2*n + 2个的数字,除其中两个数字之外其他每个数字均出现两次,找到这两个数字。 样例 给出 [1,2,2,3,4,4,5,3],返回 1和5 利用位运算操作。 Ⅱ : int类型有

LintCode 主元素 ⅠⅡⅢ

虚心学习1 虚心学习2

LintCode 寻找缺失的数

给出一个包含 0 .. N 中 N 个数的序列,找出0 .. N 中没有出现在序列中的那个数。 样例 N = 4 且序列为 [0, 1, 3] 时,缺失的数为2。 题目说的不是很清楚,意思就是如下: 给定给一个序列,有N个数,对于{0,1,2,……N}这个N+1个数的序列中,少了哪一个数? 这道题和LintCode上另一道题类似——《落单的数》 给出2*n + 1 个的数字,除其中一

跟LintCode的算法题杠上了(1334旋转数组)

题目 给定一个数组,将数组向右移动k步,其中k为非负数。 输入: [1,2,3,4,5,6,7], k = 3 输出: [5,6,7,1,2,3,4] 解释: 向右旋转1步: [7,1,2,3,4,5,6] 向右旋转2步: [6,7,1,2,3,4,5] 向右旋转3步: [5,6,7,1,2,3,4] 输入: [-1,-100,3,99], k = 2 输出: [3,99,-1,-100]

跟LintCode的算法题杠上了(1451到最近的人的最大距离)

题目 在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的。 至少有一个空座位,且至少有一人坐在座位上。 亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座位上。 返回他到离他最近的人的最大距离。 1 <= seats.length <= 20000 seats 中只含有 0 和 1,至少有一个 0,且至少有一个 1。 样例 1: 输入:[1,0