2021/3/28,今天做了个挺有意思的题,题意如下:
最开始没啥思路,瞅了一眼题解有dp和贪心的做法。首先dp的做法就是设dp[i]是长度为i的绳子乘积最大值,遍历每一个j的值,i要么减去j的值就不减了,要么减去j之后再考虑j长度的绳子,所以状态转移方程是有dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
c++参考代码:
class Solution {
public:
int cuttingRope(int n) {
vector<int> dp(100,0);
dp[2]=1;
for(int i=3;i<=n;++i)
{
for(int j=2;j<i;++j)
{
dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
}
}
return dp[n];
}
};
时间复杂度:O(N2),空间复杂度O(N)。
而贪心的做法是优先凑长度为3的绳子,具体为什么是3是因为设绳子要减x段,最大值=(n/x)x,根据求导的结果是x的最大值是n/e,所以n/(n/e)的最大值是e=2.718接近3。所以把绳子凑成若干段3,如果还剩1就让1和一个3凑一个2*2,剩2就乘上去。
c++参考代码:
class Solution {
public:
int cuttingRope(int n) {
if(n==2)
return 1;
if(n==3)
return 2;
int sum=1;
while(n>=3)
{
n-=3;
sum*=3;
}
if(n==1)
return sum/3*4;
if(n==2)
return sum*2;
return sum;
}
};
时间复杂度:O(N),空间复杂度:O(1);
参考资料
·Krahets《面试题14- I. 剪绳子(数学推导 / 贪心思想,清晰图解)》