有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,方便计算。
solution_space[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之前获得的最大分数solution_space[i , k-1]+solution_space[k+1 , j](即在k之前吹爆的:k左边第i个到第k-1个,k右边第k+1个到第j个)。综上,solution_space[i , j]=max(nums[i-1]* nums[k]* nums[j+1] + solution_space[i , k-1]+ solution_space[k+1 , j]),(对于所有的 k : i<=k<=j).
显然,求solution_space[i , j]时,需要solution_space[i , k-1] , solution_space[k+1 , j],即区间长度小于i到j的区间长度的solution_space。所以可以从区间长度为1开始求解。这个和算法导论上动态规划那一章的矩阵链乘法类似。
最后的结果为 solution_space[1 , n]。
class Solution(object):
def maxCoins(self, nums):
# n在此处为初始列表的长度,下面要对原列表首位各加上1,之后nums列表的长度会比n增加2
n=len(nums)
# 在nums列表尾部加1,方便运算
nums.append(1)
# 在nums列表首部增加1,同样是为了方便运算。
# insert函数第一个参数是增加在列表的什么位置,第二个参数是要增加的数字
nums.insert(0,1)
# 这一步完成对这个问题解空间的一种初始化
# solution_space[i][j]代表了刚才说的吹爆第i个气球到第j个气球能获得的最高分数
solution_space=[[0 for x in range(n+2)] for y in range(n+2)]
# 此处的length表示了动态规划从下向上递增的序列,
# 从 如果只吹爆一个气球的最高分开始,到只吹爆两个得到的最高分...逐步增加
for length in range(1,n+1):
# i表示了解空间solution_space[i][j]这个矩阵中的横行
# 随着length的值逐渐变大(解空间变大)i的循环次数会逐渐变少
# 注意:因为解空间大小是按照两头加过1以后的长度来建立的第0行和第5行其实全部都是0
# 因此只会计算解空间(大矩阵)中[1][1]到[4][4]右上半部分
for i in range(1,(n+2)-length):
# 同理,j表示了解空间solution_space[i][j]这个矩阵中的纵行
j=i+length-1
# 变量初始化,q存储了递推式每次算出来的临时结果
q=0
# k代表了最后一个被吹爆的气球的位置,来源于i和j之间
for k in range(i,j+1):
#此处为之前推导的递推式求解
q=nums[i-1]*nums[k]*nums[j+1]+solution_space[i][k-1]+solution_space[k+1][j]
# 每轮循环循环的最大答案将会保留在解空间的矩阵中
if q>solution_space[i][j]:
solution_space[i][j]=q
return solution_space[1][n]
以上内容引用了六种鱼的博客。点击这里看原答案