剑指offer:剪绳子

时间:2020-04-28
本文章向大家介绍剑指offer:剪绳子,主要包括剑指offer:剪绳子使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题意描述

给你一根长度为n的绳子,请把绳子剪成整数长的m段(m、n都是整数,n>1并且m>1),每段绳子的长度记为k[0],k[1],...,k[m]。请问k[0]xk[1]x...xk[m]可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

一、思路一

题目分析:

  • 先举几个例子,可以看出规律来。
  • 3: 1 * 2
  • 4 : 2 * 2
  • 5 : 2 * 3
  • 6 : 3 * 3
  • 7 : 2 * 2 * 3 或者4 * 3
  • 8 : 2 * 3 * 3
  • 9 : 3 * 3 * 3
  • 10:2 * 2 * 3 * 3 或者4 * 3
  • 11:2 * 3 * 3 * 3
  • 12:3 * 3 * 3 * 3
  • 13:2 * 2 * 3 * 3 * 3 或者4 * 3 * 3 * 3

如上图所示,每个输入的乘积最大就是:3^n * 2 * k , k=0,1,2

    public int cutRope(int target) {
        	//1 = 1,2 = 1*1, 3 = 1*2
            if(target <= 3 && target >0) return target-1;
             int max = 1;
        	//当target《=4,不再循环,此时target = 0(0*2),1,2(1*2),3,4(2*2)
            while(target > 4){	
                target -= 3;
                max *= 3;
            }
            return target*max;
        }

二、思路二

使用动态规划。

  1. 当target《=3时,对target进行分段,只有一种选择。1 = 1,2 = 1 * 1,3 = 1 * 2
  2. 当target》=4时,对target进行分段,有多种选择。例如:4 = 1 * 3、2 * 2
  3. 记录每种分段的最大值。
    public int cutRope(int target) {
        	//target=2、3,乘积《target
            if(target == 2) return 1;	
            if(target == 3) return 2;
            int[] dp = new int[target+1];
        	//当target=1、2、3时,不分段就是最大值。
            dp[1] = 1;	
            dp[2] = 2;
            dp[3] = 3;
            int res = 0;
        	//当target》=4时,乘积开始》=target。
            for(int i=4;i<=target;i++){
                for(int j=1;j<=i/2;j++){	//只计算前一半,当target=3时,1 * 3 = 3 * 1
                    res = Math.max(res,dp[j]*dp[i-j]);
                }
                dp[i] = res;
            }
            return dp[target];
        }

原文地址:https://www.cnblogs.com/le-le/p/12794008.html