打气球的最大分数

题目描述

给定一个数组arr,长度为n。代表排有分数的气球。 每打爆一个气球都能获得分数,假设打爆气球的分数为X,获得分数的规则如下:
1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为R.获得分数为L*X*R
2)如果被打爆的气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为L:如果被打爆气球的右边所有气球都已经被打爆,获得分数为L*X。
3)如果被打爆气球的左边所有的气球都已经被打爆:如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球。获得分数为X*R.
4)如果被打爆气球的左边和右边所有的气球都已经被打爆。获得分数为X。
目标是打爆所有气球,获得每次打爆的分数。通过选择打爆气球的顺序,可以得到不同的总分,请返回能获得的最大分数。

思路

动态规划。
假设当前目标是打破[L…R]上的气球,且L-1和R+1位置上的气球都没有破。设dp[L][R]为打破[L…R]上气球的最大分数。方法是考虑这个区间上最后一个气球的打破方式,即最后一个气球的打破位置。
根据最后一个气球的打破位置,有以下几种情况:

  1. 最后一个气球在L位置上,说明先打破了[L+1…R]位置上的气球,获得的分数为dp[L+1][R]。此时这个气球左边的气球就是L-1位置上的气球,右边的气球就是R+1位置上的气球。所以打破[L…R]上气球的最大分数就是arr[L-1]*arr[L]*arr[R+1]+dp[L+1][R]。
  2. 最后一个气球在i位置上,L+1<=i<=R-1,说明先打破了[L…i-1]位置上和[i+1…R]的气球,获得的分数为dp[L][i-1] + dp[i+1][R]。此时这个气球左边的气球就是L-1位置上的气球,右边的气球就是R+1位置上的气球。所以打破[L…R]上气球的最大分数就是arr[L-1]*arr[i]*arr[R+1]+dp[L][i-1]+dp[i+1][R]。
  3. 最后一个气球在R位置上,说明先打破了[L…R-1]位置上的气球,获得的分数为dp[L][R-1]。此时这个气球左边的气球就是L-1位置上的气球,右边的气球就是R+1位置上的气球。所以打破[L…R]上气球的最大分数就是arr[L-1]*arr[R]*arr[R+1]+dp[L][R-1]。
    因为题目要求的是最大分数,所以应该是上述R-L+1种情况的最大值。

求dp数组时,应该先在纸上画出二维表格,标记出哪些位置应该求,进一步标记出一个位置的求解依赖于哪些位置,然后从最初始的位置进行求解。

因为要求整个dp数组,每个位置的求解复杂度又是O(n),所以总的时间复杂度为O(n^3)。

代码实现

import java.util.Scanner;
public class Main{
   
    public static void main(String []args){
   
        Scanner scanner = new Scanner(System.in);
        
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值