剑指Offer-14-剪绳子/力扣-343-整数拆分
动态规划
动态规划的思路是什么?
对于一段绳子,第一刀下去可以将绳子分成i和n-i两段,其中i的取值范围为[1,n-1]
dp[n]表示n可分成的最大乘积和,dp[n] = max(dp[n],max(i*n-i,i*f(n-i)))
初始化:全部初始化为1
为什么有两层max()
要与一个额外的i-j
作比较?因为dp[i-j]
代表的是将绳子 break 之后的最大值,缺少一个不 break 的情况
int cuttingRope(int n) { vector<int> dp(n, 1); for (int i = 2; i <= n; i++) { for (int j = 1; j < (i + 1) / 2; j++) { dp[i - 1] = max(max(j * dp[i - j - 1], j + i - j), dp[i - 1]); } } return dp[n - 1]; }
这里的 dp 数组不能被优化成常数个变量
Ⅱ
和 Ⅰ 有什么区别?多了一步取模运算,Ⅱ 的数据范围更大了,从 58 变成了 1000,不在过程中取模是不可能的了,因为 INT 范围肯定会超,那么就不能用动态规划了,也就是说题目是要求换一种方法求解
贪心
我觉得想出来贪心策略…怎么证明是个数学问题,怎么想出来则是一个玄学问题
力扣的编译器 res 用 int 怎么都会中间计算溢出,所以定义为 long
int MOD = 1e9 + 7; int cuttingRope(int n) { // 当 n >= 5 时,尽可能多地去剪长度为 3 的绳段 // 2->1,3->2,4->4,5->6 if (n < 4)return n - 1; long res = 1; while (n >= 5) { res = (res * 3) % MOD; n -= 3; } return (res * n) % MOD; }
本文作者:YaosGHC
本文链接:https://www.cnblogs.com/yaocy/p/16821991.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步