2021-02-26:一個數組arr是二叉樹的中序遍歷結果,每條邊的開銷是父節點和子節點的乘積,總開銷是全部邊

2021-02-26:一個數組arr是二叉樹的中序遍歷結果,每條邊的開銷是父節點和子節點的乘積,總開銷是全部邊的開銷之和。請問最小總開銷是多少?golang

連接:https://www.nowcoder.com/ques...
來源:牛客網數組

小團有一個由N個節點組成的二叉樹,每一個節點有一個權值。定義二叉樹每條邊的開銷爲其兩端節點權值的乘積,二叉樹的總開銷即每條邊的開銷之和。小團按照二叉樹的中序遍歷依次記錄下每一個節點的權值,即他記錄下了N個數,第i個數表示位於中序遍歷第i個位置的節點的權值。以後因爲某種緣由,小團遺忘了二叉樹的具體結構。在全部可能的二叉樹中,總開銷最小的二叉樹被稱爲最優二叉樹。如今,小團請小美求出最優二叉樹的總開銷。ui

輸入描述:
第一行輸入一個整數N(1<=N<=300),表示二叉樹的節點數。
第二行輸入N個由空格隔開的整數,表示按中序遍歷記錄下的各個節點的權值,全部權值均爲不超過1000的正整數。spa

輸出描述:
輸出一個整數,表示最優二叉樹的總開銷。code

福哥答案2021-02-26:blog

天然智慧便可。
1.遞歸。有代碼。
2.記憶化搜索。有代碼。遞歸

代碼用golang編寫,代碼以下:圖片

package main

import "fmt"

const MAX = int(^uint(0) >> 1)

//https://www.nowcoder.com/questionTerminal/0d939e874a004f449a370aca1346dd5c
func main() {
    arr := []int{7, 6, 5, 1, 3}
    ret := f1(arr)
    fmt.Println("1.遞歸:", ret)

    ret = f2(arr)
    fmt.Println("2.記憶化搜索:", ret)
}

func f1(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    return process1(arr, -1, 0, arrLen-1)
}

func process1(arr []int, cur int, L int, R int) int {
    length := R - L + 1
    if length == 0 {
        return 0
    }
    ans := MAX
    for i := L; i <= R; i++ {
        temp := 0
        if cur >= 0 {
            temp = arr[cur] * arr[i]
        }
        ans = getMin(temp+process1(arr, i, L, i-1)+process1(arr, i, i+1, R), ans)
    }
    return ans

}

func f2(arr []int) int {
    arrLen := len(arr)
    if arrLen <= 1 {
        return 0
    }
    dp := make([][][]int, arrLen+1)
    for i := 0; i < arrLen+1; i++ {
        dp[i] = make([][]int, arrLen)
        for j := 0; j < arrLen; j++ {
            dp[i][j] = make([]int, arrLen)
            for k := 0; k < arrLen; k++ {
                dp[i][j][k] = -1
            }
        }
    }

    ret := process2(arr, -1, 0, arrLen-1, dp)
    //fmt.Println(dp)
    return ret
}

func process2(arr []int, cur int, L int, R int, dp [][][]int) int {
    length := R - L + 1
    if length == 0 {
        return 0
    }
    if dp[cur+1][L][R] != -1 {
        //fmt.Println("記憶化", dp[cur+1][L][R])
        return dp[cur+1][L][R]
    }
    ans := MAX
    for i := L; i <= R; i++ {
        temp := 0
        if cur >= 0 {
            temp = arr[cur] * arr[i]
        }
        ans = getMin(temp+process2(arr, i, L, i-1, dp)+process2(arr, i, i+1, R, dp), ans)
    }
    dp[cur+1][L][R] = ans
    return ans

}
func getMin(a int, b int) int {
    if a < b {
        return a
    } else {
        return b
    }
}

執行結果以下:
在這裏插入圖片描述rem


評論get

相關文章
相關標籤/搜索