前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >2021-04-29:给定一个数组 arr,代表一排有分数的气球。每打爆一

2021-04-29:给定一个数组 arr,代表一排有分数的气球。每打爆一

原创
作者头像
福大大架构师每日一题
修改2021-05-04 22:25:50
2970
修改2021-05-04 22:25:50
举报

2021-04-29:给定一个数组 arr,代表一排有分数的气球。每打爆一个气球都能获得分数,假设打爆气 球 的分数为 X,获得分数的规则如下: 1)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为 L;如果被打爆气球的右边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为 R。 获得分数为 L_X_R。 2)如果被打爆气球的左边有没被打爆的气球,找到离被打爆气球最近的气球,假设分数为 L;如果被打爆气球的右边所有气球都已经被打爆。获得分数为 L_X。 3)如果被打爆气球的左边所有的气球都已经被打爆;如果被打爆气球的右边有没被打爆的 气球,找到离被打爆气球最近的气球,假设分数为 R;如果被打爆气球的右边所有气球都 已经 被打爆。获得分数为 X_R。 4)如果被打爆气球的左边和右边所有的气球都已经被打爆。获得分数为 X。目标是打爆所有气球,获得每次打爆的分数。通过选择打爆气球的顺序,可以得到不同的总分,请返回能获得的最大分数。【举例】arr = {3,2,5} 如果先打爆3,获得3_2;再打爆2,获得2_5;最后打爆5,获得5;最后总分21 如果先打爆3,获得3_2;再打爆5,获得2_5;最后打爆2,获得2;最后总分18 如果先打爆2,获得3_2_5;再打爆3,获得3_5;最后打爆5,获得5;最后总分50 如果先打爆2,获得3_2_5;再打爆5,获得3_5;最后打爆3,获得3;最后总分48 如果先打爆5,获得2_5;再打爆3,获得3_2;最后打爆2,获得2;最后总分18 如果先打爆5,获得2_5;再打爆2,获得3_2;最后打爆3,获得3;最后总分19 返回能获得的最大分数为50。

福大大 答案2021-04-29:

动态规划。

代码用golang编写。代码如下:

代码语言:txt
复制
package main

import (
    "fmt"
)

func main() {
    arr := []int{2, 2, 2}
    ret := maxCoins1(arr)
    fmt.Println(ret)

    ret = maxCoins2(arr)
    fmt.Println(ret)
}

func maxCoins1(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    if len(arr) == 1 {
        return arr[0]
    }
    N := len(arr)
    help := make([]int, N+2)
    help[0] = 1
    help[N+1] = 1
    for i := 0; i < N; i++ {
        help[i+1] = arr[i]
    }
    return process(help, 1, N)
}

// 打爆arr[L..R]范围上的所有气球,返回最大的分数
// 假设arr[L-1]和arr[R+1]一定没有被打爆
func process(arr []int, L int, R int) int {
    if L == R { // 如果arr[L..R]范围上只有一个气球,直接打爆即可
        return arr[L-1] * arr[L] * arr[R+1]
    }
    // 最后打爆arr[L]的方案,和最后打爆arr[R]的方案,先比较一下
    max := getMax(arr[L-1]*arr[L]*arr[R+1]+process(arr, L+1, R),
        arr[L-1]*arr[R]*arr[R+1]+process(arr, L, R-1))
    // 尝试中间位置的气球最后被打爆的每一种方案
    for i := L + 1; i < R; i++ {
        max = getMax(max, arr[L-1]*arr[i]*arr[R+1]+process(arr, L, i-1)+process(arr, i+1, R))
    }
    return max
}

func maxCoins2(arr []int) int {
    if len(arr) == 0 {
        return 0
    }
    if len(arr) == 1 {
        return arr[0]
    }
    N := len(arr)
    help := make([]int, N+2)
    help[0] = 1
    help[N+1] = 1
    for i := 0; i < N; i++ {
        help[i+1] = arr[i]
    }
    dp := make([][]int, N+2)
    for i := 0; i < N+2; i++ {
        dp[i] = make([]int, N+2)

    }
    for i := 1; i <= N; i++ {
        dp[i][i] = help[i-1] * help[i] * help[i+1]
    }
    for L := N; L >= 1; L-- {
        for R := L + 1; R <= N; R++ {
            ans := help[L-1]*help[L]*help[R+1] + dp[L+1][R]
            ans = getMax(ans, help[L-1]*help[R]*help[R+1]+dp[L][R-1])
            for i := L + 1; i < R; i++ {
                ans = getMax(ans, help[L-1]*help[i]*help[R+1]+dp[L][i-1]+dp[i+1][R])
            }
            dp[L][R] = ans
        }
    }
    return dp[1][N]
}

func getMax(a int, b int) int {
    if a > b {
        return a
    } else {
        return b
    }
}

执行结果如下:

图片
图片

***

左神java代码

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com