剪绳子


描述

示例

思路

这道题为动态规划相关题目,动态规划相关知识见知乎动态规划

一旦分出一段长度为1的小段,只会减少总长度,还不能增加乘积,因此长度为2的绳子不分比分开的乘积大,长度为3的绳子不分比分开的乘积大,长度为4的绳子分成2*2比较大。前面的我们都可以通过这样递推得到,后面的呢? 同样递推!如果我有一个长度为n的绳子,我们要怎么确定其分出最大的乘积,我们可以尝试其中一段不可分的为j,那么如果另一段n−j最大乘积已知,我们可以遍历所有j找到这个最大乘积。因此用dp[i]表示长度为i的绳子可以被剪出来的最大乘积,那么后续遍历每个j的时候,我们取最大p[i]=max(dp[i],j∗dp[i−j])就好了。

具体做法

  • 检查当number不超过3的时候直接计算。
  • 用dp数组表示长度为i的绳子可以被剪出来的最大乘积,初始化前面4个容易推断的。
  • 遍历每个长度,对于每个长度的最大乘积,可以遍历从1到i的每个固定一段,按照上述公式求的最大值。
  • 最后数组最后一位就是答案。

代码

#include <algorithm>
#include<vector>
using namespace std;
class Solution {
  public:
    int cutRope(int n) {
        if (n < 2 || n > 60) return -1;
        if (n == 3 || n == 2) return n - 1;
        vector<int> dp(n + 1, 0);
        dp[1] = 1;
        dp[2] = 2;   //n若为2,因为m>1,则dp为1,n大于3时长度为2可以不切,则dp为2
        dp[3] = 3;
        dp[4] = 4;
        //遍历后续每一个长度
        for (int i = 5; i <= n; i++)
            //可以被分成两份
            for (int j = 1; j < i; j++)
                //取最大值
                dp[i] = max(dp[i], j * dp[i - j]);
        return dp[n];
    }
};

声明:技术分享爱好者|版权所有,违者必究|如未注明,均为原创|本网站采用BY-NC-SA协议进行授权

转载:转载请注明原文链接 - 剪绳子


Carpe Diem and Do What I Like