[leetCode]剑指 Offer 14- I. 剪绳子

动态规化
使用动态规化的问题有一下特点:
- 目标是求解问题的最优解
- 整体问题的最优解依赖各个子问题的最优解
- 把大问题分解为小问题,各个小问题之间存在重叠部分
- 从上往下分析问题,从下往上求解问题
设
    
     
      
       
        f
       
       
        (
       
       
        n
       
       
        )
       
      
      
       f(n)
      
     
    f(n)为把长度为n的绳子剪成若干段后乘积的最大值,则第一次剪的时候优n-1中选择,一段绳子的长度可能为1,2,3…n-1,因此
    
     
      
       
        f
       
       
        (
       
       
        n
       
       
        )
       
       
        =
       
       
        m
       
       
        a
       
       
        x
       
       
        (
       
       
        f
       
       
        (
       
       
        i
       
       
        )
       
       
        ∗
       
       
        f
       
       
        (
       
       
        n
       
       
        −
       
       
        1
       
       
        )
       
       
        )
       
      
      
       f(n) = max(f(i)*f(n-1))
      
     
    f(n)=max(f(i)∗f(n−1))。可以从下至上求解该问题,
    
     
      
       
        f
       
       
        (
       
       
        2
       
       
        )
       
       
        =
       
       
        1
       
       
        ,
       
       
        f
       
       
        (
       
       
        3
       
       
        )
       
       
        =
       
       
        2
       
      
      
       f(2) = 1, f(3)=2
      
     
    f(2)=1,f(3)=2,代码如下:
class Solution {
    public int cuttingRope(int n) {
        if(n < 2) return 0;
        if(n == 2) return 1;
        if(n == 3) return 2;
        int[] products = new int[n+1];
        products[0] = 0;
        products[1] = 1;
        products[2] = 2;
        products[3] = 3;
        //products[i]表示把长度为i的绳子剪成若干段后乘积的最大值
        int max = 0;
        for(int i = 4; i <= n; i++){
            for(int j = 1; j <= i/2; j++){
                int product = products[j] * products[i-j];
                if(product > max){
                    max = product;
                }
                products[i] = max;
            }
        }
        return max;
    }
}
贪婪算法
使用贪婪算法解决问题时,每一步做一个贪婪的选择,基于这个选择达到最优解。
 这题思路是:当n>=5时尽可能多的剪长度为3的绳子,当剩下绳子长度为4时剪成两段长度为2的绳子。
class Solution {
    public int cuttingRope(int n) {
        if(n < 2) return 0;
        if(n == 2) return 1;
        if(n == 3) return 2;
        //尽可能减去长度为3的绳子段
        int timesOf3 = n/3;
        //最后一段绳子长度为4时不能减去3
        if(n - timesOf3 * 3 == 1){
            timesOf3 -= 1;
        }
        //减长度为4的绳子
        int timesOf2 = (n - timesOf3 * 3)/2;
        return (int)(Math.pow(3,timesOf3) * Math.pow(2,timesOf2));
    }
}

 
                
            
         浙公网安备 33010602011771号
浙公网安备 33010602011771号