题意分析

  • 题目的意思是给出一个数字,让我们将这个数字进行分解,然后找到分解后所有的数的乘积最大的情况。
  • 样例分析,我们可以将8分解为2x3x3,得到的结果就是18,这个可以自己暴力枚举一下所有的情况进行验证。

思路分析

  • 这个题目,我主要用的是三种方法进行解答

解法一 暴力枚举

  • 我们可以发现,我们进行从小到大的枚举,当我们进行求解某一个数字的时候,我们已经求出了之前的所有的数的最优的情况,那么我们可以枚举将这个数字x分解出1,2,...x-1的所有的情况,然后维护最大的值就行了。
  • 代码如下
    • 开了双重for循环,时间复杂度为O(n^2)
    • 开了数组存储每个状态的最优解,空间复杂度为O(n)
      class Solution {
      public:
      int f[100]; // 用来维护当前所有的数字的最优解的值
      int cutRope(int number) {
        // 处理特殊的情况
        if(number<=3){
            return number-1;
        }
        for(int i=2;i<=number;i++){
            if(i<=3){
                f[i]=i;
            }
            // 暴力枚举将这个数字分解出j后的情况,维护最大的值
            for(int j=1;j<i;j++){
                f[i]=max(f[i],f[j]*(i-j));
            }
        }
        return f[number];
      }
      };

解法二 递归求解

  • 我们可以发现,当我们求某一个数字的时候,我们只需要将这个数字分解出一个1,2,3。对于3以上的数字,其实可以分解成这三个数字,比如4=2x2,5=2x3。对于分解出1的情况,我们发现这个是对答案没有贡献的。所以直接忽略。我们只需要讨论2和3的情况。所以,我们只需要将数字分为2和3组成的就行了。

  • 如下图
    图片说明

  • 代码如下,

    • 需要对每个状态进行求解,时间复杂度为O(n)
    • 只开了几个变量进行存储,空间复杂度为O(1)
      class Solution {
      public:
      int dp(int x){
        // 递归出口
        if(x<=3){
            return x;
        }
        // 将数字划分出一个2或者3维护最大的值即可
        return max(dp(x-2)*2,dp(x-3)*3);
      }
      int cutRope(int number) {
        return dp(number);
      }
      };

解法三 找规律

  • 我们发现,最优的解一定是将这个数字尽量平均分为若干份进行求解。我们假设我们存在一个数字为x,我们将这个数字平均分为尽量m等份,那么每一份就是x/m(假设可以等分),乘积就是,我们令x/m=y,那么就是y^m,我们从这里面抽取出两份y,加入我们把这两份不进行均分,那么就是(y-1),(y+1),我们发现,其结果肯定是比y^2小的。依次类推,我们可以得到结论,尽量将这个数字均分成若干等份就是最优的答案。所以我们可以枚举分成的份数。对于不能均分的情况,我们就把多余的尽量给每份分一个。
  • 代码如下
    • 从1-number进行遍历,时间复杂度O(n)
    • 只开了少数几个变量存储,空间复杂度为O(1)
      class Solution {
      public:
      int cutRope(int number) {
        int ans=0;
        // 枚举分成的份数多少
        for(int i=1;i<=number;i++){
            int pre=number/i;
            int more=number%i;
            int res=1;
            for(int j=1;j<=more;j++){
                res=res*(pre+1);
            }
            // 对于余数,我们就给余数份多分一个就行
            for(int j=more+1;j<=i;j++){
                res=res*pre;
            }
            ans=max(ans,res);
        }
        return ans;
      }
      };