剑指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))

    按照如下的策略剪绳子,则得到的各段绳子的长度的乘积最大:

  • 当n>=5时,尽可能多地剪长度为3的绳子;
  • 当剩下的绳子长度为4时,把绳子剪成两段长度为2的绳子。

也就是

  • 当n能被3整除时,乘积=3^(n/3);
  • 当n除3余1时,这时候发现多了一个1,于是拿出前面的一个3,然后把这个1和前面那个3分解为2*2,所以乘积为 3^(n/3 - 1) * 4;
  • 当n除3余2时,乘积为3^(n/3) * 2

 

☆☆解法1(动态规划)

 

 https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/jian-zhi-offer-14-i-jian-sheng-zi-huan-s-xopj/

 

☆☆解法2(贪婪算法)

public class Solution {
    public int cutRope(int target) {
        if (target == 2)
            return 1;
        if (target == 3)
            return 2;
        if (target % 3 == 0){
            return (int)Math.pow(3,target / 3); // 全3
        }else if (target % 3 == 1){
            return (int) Math.pow(3,target / 3 - 1) * 4;
        }else{ // target % 3 == 2
            return (int) Math.pow(3, target / 3) * 2;
        }
    }
}

 

 

posted @ 2020-09-15 18:30  不学无墅_NKer  阅读(154)  评论(0编辑  收藏  举报