1. 程式人生 > 實用技巧 >劍指67.剪繩子

劍指67.剪繩子

題目描述

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

思路

應用動態規劃求解問題的特點:

  • 題目是求一個問題的最優解(最大值或最小值);
  • 該問題能分解成若干個子問題(整體問題的最優解依賴各個子問題的最優解);
  • 子問題之間還有相互重疊的更小的子問題;
  • 從上往下分析問題,從下往上求解問題(把已經解決的子問題的最優解儲存到數組裡,並把子問題的最優解組合起來逐步解決大問題)
  • 每一步都可能面臨若干個選擇,只能把所有的可能都嘗試一遍。

貪婪演算法和動態規劃不一樣。應用貪婪演算法解決問題時,每一步都可以做出一個貪婪的選擇,基於這個選擇,確定能夠得到最優解。

思路1:動態規劃。 (時間複雜度:O(n^2), 空間複雜度:O(n))

思路2:貪婪演算法。 (時間複雜度:O(1),空間複雜度:O(1))

☆☆解法1(動態規劃)

public class Solution {
    //動態轉移的方程為:dp[n] = dp[n - i] * dp[i],列舉i即可(1~n/2)
    public int cutRope(int target) {
        
int[] dp = new int[target + 1]; // 0 ~ target if (target == 2) return 1; if (target == 3) return 2; dp[1] = 1; dp[2] = 2; dp[3] = 3; for (int i = 4; i <= target; i++) { for (int j = 1; j <= i / 2; j++) { dp[i]
= Math.max(dp[i], dp[j]*dp[i-j]); } } return dp[target]; } }

Note: n<=3時,要分段。但是n>=4時,3就不要再分了,因為3分段要小於3,我們要記錄最大的。

解法2(貪婪演算法)

M