已解决
剑指Offer-剪绳子
来自网友在路上 147847提问 提问时间:2023-11-12 13:03:05阅读次数: 47
最佳答案 问答题库478位专家为你答疑解惑
剑指Offer-剪绳子
题目描述
LCR 131. 砍竹子 I
现需要将一根长为正整数 bamboo_len
的竹子砍为若干段,每段长度均为正整数。请返回每段竹子长度的最大乘积是多少。
示例 1:
输入: bamboo_len = 12
输出: 81
提示:
2 <= bamboo_len <= 58
思路
参考了力扣的两位大神的思路。
数学解法
通过数学可证明
设n = n1+n2+n3…n,使得n1 * n2 * n3…*n 最大,有结论: 1. 当n1= n2 = n3 = …n 时乘积最大 2. 当每段n1=3时,乘积最大
证明过程省略
代入此题可知,我们需要将竹子分成n段长度为3的小竹子,但是竹子总长不一定是3的倍数,因此最后一段竹子的长度有以下可能:
- 1:此时最大乘积应该由 pow(3,n) 变成pow(3,n-1)*4,原因是需要将最后一段长度为1的竹子与上一段长度为三的竹子合体,因为2x2 > 3x1
- 2:直接x2,返回pow(3,n-1)*2
另外一种特殊情况则是总长度一开始便不满足3的长度,题目限制了最小为2,因此如果长度为2时,返回1,长度为3时返回2即可。
代码如下
class Solution {
public:int cuttingBamboo(int bamboo_len) {if(bamboo_len <= 3)return bamboo_len-1;int b = bamboo_len%3;int a = bamboo_len/3;if(b == 0)return pow(3,a);if(b == 1)return 4*pow(3,a-1);return 2*pow(3,a);}
};
动态规划
按照动态规划五部曲,有如下操作:
- 状态方程:dp[i]: 代表长度为i的竹子被分成m段的最大乘积
- 状态转移:dp[i] = max(dp[i], max(dp[j] * (i-j), j * (i-j)))
- 遍历:正序遍历,2<= i <=bamboo_len 1<= j <i
- 初始化:dp[0] = d[1] = 0 , 因为长度0和1都不可以继续划分,或者dp[1]也可以理解为分成长度为1和长度为0的部分,因此dp[1] 也可以=1
- 最后返回:dp[n]
代码如下
class Solution {
public:int cuttingBamboo(int bamboo_len) {vector<int> dp(bamboo_len+1);dp[1] = 1;for(int i=2;i<=bamboo_len;i++){for(int j=1;j<i;j++){dp[i] =max(dp[i], max(dp[j]*(i-j),j*(i-j)));}}return dp[bamboo_len];}
};
查看全文
99%的人还看了
相似问题
猜你感兴趣
版权申明
本文"剑指Offer-剪绳子":http://eshow365.cn/6-38079-0.html 内容来自互联网,请自行判断内容的正确性。如有侵权请联系我们,立即删除!
- 上一篇: 采集摄像头数据的Golang应用
- 下一篇: Python之函数进阶-匿名函数