JZ67 剪繩子

剪繩子

題目:給你一根長度爲n的繩子,請把繩子剪成整數長的m段(m、n都是整數,n>1並且m>1,m<=n),每段繩子的長度記爲k[1],...,k[m]。請問k[1]x...xk[m]可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別爲2、3、3的三段,此時得到的最大乘積是18。

輸入一個數n,意義見題面。(2 <= n <= 60)

思路:

推導規律
就是找規律,嘗試着寫出 n 取不同的值時對應的乘積,可發現規律:當 n>6 時,ans(n) = ans(n-3) x 3
動態規劃
大數越界情況不適用

首先定義狀態:dp[i]表示長爲i的繩子的最大乘積
狀態轉移方程:dp[i] = max(j段繩子最大值 * i - j段繩子最大值)

// 動態規劃方法
func cuttingRope(n int) int {  
    dp := make(map[int]int)
    dp[1] = 1
    for i := 2; i < n+1; i++ {
        // 切割點爲j,j屬於[1,i],這裏參照了他人的優化技巧
        for j := 1; j < (i/2 + 1); j++ {
            dp[i] = max(dp[i], max(j, dp[j])*max(i-j, dp[i-j]))
        }
    }
    return dp[n]
}

func max(i, j int) int {
    if i > j {
        return i
    }
    return j
}


// 遞歸,大數越界的情況下不適用動態規劃
func cuttingRope(n int) int {
    switch n {
    case 2:
        return 1
    case 3:
        return 2
    case 4:
        return 4
    case 5:
        return 6
    case 6:
        return 9
    default:
        return cuttingRope(n-3) * 3 % 1000000007
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章