剪繩子
題目:給你一根長度爲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 } }