[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(n1))。可以从下至上求解该问题, 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));
    }
}
posted @ 2020-08-09 08:52  消灭猕猴桃  阅读(61)  评论(0编辑  收藏  举报