2022-10-24 16:50阅读: 21评论: 0推荐: 0

剑指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 中国大陆许可协议进行许可。

posted @   YaosGHC  阅读(21)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起