2021-04-16:摆放着n堆石子。现要将石子有次序地合并成一堆,规定每次只能选相邻的2堆石子合并成新的一堆,

2021-04-16:摆放着n堆石子。现要将石子有次序地合并成一堆,规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。求出将n堆石子合并成一堆的最小得分(或最大得分)合并方案。

福大大 答案2021-04-16:

动态规划。

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

package main

import (
    "fmt"
    "math"
)

func main() {
    arr := []int{1, 4, 2, 3}
    ret := StoneMerge(arr)
    fmt.Println(ret)

}
func sum(arr []int) []int {
    N := len(arr)
    s := make([]int, N+1)
    s[0] = 0
    for i := 0; i < N; i++ {
        s[i+1] = s[i] + arr[i]
    }
    return s
}
func w(s []int, l int, r int) int {
    return s[r+1] - s[l]
}
func StoneMerge(arr []int) int {
    if len(arr) < 2 {
        return 0
    }
    N := len(arr)
    s := sum(arr)
    dp := make([][]int, N)
    for i := 0; i < N; i++ {
        dp[i] = make([]int, N)
    }
    best := make([][]int, N)
    for i := 0; i < N; i++ {
        best[i] = make([]int, N)
    }
    for i := 0; i < N-1; i++ {
        best[i][i+1] = i
        dp[i][i+1] = w(s, i, i+1)
    }
    for L := N - 3; L >= 0; L-- {
        for R := L + 2; R < N; R++ {
            next := math.MaxInt64
            choose := -1
            for leftEnd := best[L][R-1]; leftEnd <= best[L+1][R]; leftEnd++ {
                cur := dp[L][leftEnd] + dp[leftEnd+1][R]
                if cur <= next {
                    next = cur
                    choose = leftEnd
                }
            }
            best[L][R] = choose
            dp[L][R] = next + w(s, L, R)
        }
    }
    return dp[0][N-1]
}

执行结果如下:
图片


左神java代码
评论

福大大架构师每日一题 文章被收录于专栏

最新面试题,针对高级开发人员和架构师。内容是后端、大数据和人工智能。

全部评论

相关推荐

03-26 13:04
已编辑
电子科技大学 算法工程师
xiaowl:你这个简历“条目上”都比较有深度性,但是实际上面试官又没法很好的评估你是怎么达到很多看上去很厉害的结果的。要避免一些看上去很厉害的包装,比如高效的内存复用策略的表达,如果仅是简单的一些内存共享机制,而且面试上也没有深挖的空间,就不要这样表达。比如,工程化模式本质上可能就是定义了一些abstract class,那也就没特别多值得讲的内容。建议简历上应该侧重那些你花了大量时间和精力解决、研究的问题,不要过分追求“丰富”,而是关注在技术深入度、问题解决能力的表现上。
没有实习经历,还有机会进...
点赞 评论 收藏
分享
03-24 17:57
门头沟学院 Java
yakuso:你这头像哈哈哈
点赞 评论 收藏
分享
评论
3
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务