剑指 Offer 14- I. 剪绳子(C++暴力+动态规划、贪心解)
一、题目
剑指 Offer 14- I. 剪绳子
题目描述
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
示例1:
1 | 输入: 2 |
示例2:
1 | 输入: 10 |
二、分析
方法1 暴力+动态规划
这道题剪绳子,我们用动态规划的思想去做。
- 假设动态规划 f(i)表示i长的绳子切割后最大长度 $f(i)=max((i-k)k,f(i-k)k))其中k=[2,i)$,k表示第一段割下来的长度
- 依次从i长的绳子里面割j长的绳子.剩下的$(i-j)$长绳子可以不再分割:最大乘积就为$(i - j) * j$。
- 也可以再次分割,最大乘积就为:$j * dp[i - j]$。两者取最大。
- 而最外面的max是因为第一段可以割不同的$j$(暴力思想),需要不断更新。
方法2 贪心算法
要考虑尽可能每一段都要分隔成3的长度。
将特殊情况绳长小于等于3情况的去除掉
将绳长大于4的情况,不断切割下3的绳子,可能最后剩下4,3,2,剩下的正好作为单独一段。
注意:这里为什么条件是大于4,而不是大于当于4。因为如果等于4,那么4就会在被分隔成3+1 ,这两段乘积3x1=3。我们知道4切割后最大的乘积应该是2x2=4。因此我们这里干脆将条件设为大于4,那么最后就可能剩下一段绳子长度为4。正好符合4切割后的最大乘积4。
三、代码
方法1 暴力+动态规划
1 | /* |
方法2 贪心算法
1 | /* |
四、总结
这道题核心是想到用动态规划的思想来做。可能第二种贪心算法在有限时间内不容易证明出来,但是第一种动态规划思想还是比较常见,应该要会掌握。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 坚韧的长线「串联」散落的珍珠!
评论