343. Integer Break
来源:互联网 发布:毕业论文的数据分析 编辑:程序博客网 时间:2024/06/07 01:45
Given a positive integer n, break it into the sum of at least two positive integers and maximize the product of those integers. Return the maximum product you can get.
For example, given n = 2, return 1 (2 = 1 + 1); given n = 10, return 36 (10 = 3 + 3 + 4).
Note: You may assume that n is not less than 2 and not larger than 58.
这一题是给一个数字n,将n拆分为k(k >= 2)个数字, 使得n = x1 + x2 + ... + xk
然后计算x1 * x2 * ... * xk,使得积最大
我们来找递推关系
设f(n)为最佳的拆分选择,那么f(n) = max{f(n-x) * x}, 0<x<n
那么我们的动态规划程序可以如下:
int integerBreak(int n) {
int save[59]; //保存数据
save[1] = 1;
save[2] = 1; //第一个数
for (int i = 3; i <= n; i++){
save[i] = 0;
for (int j = 1; j < i; j++)
save[i] = max(save[i], (i-j) * save[j]);
}
return save[n];
}
这个代码看似正确,实际上其中含着一个致命的bug
我们容易知道,save[2] = 1 < 2, save[3] = 2 < 3,这两个数的拆分后的积是小于自己的
那么,利用到这两个值的数就会出错。例如,我们容易知道 5 = 2 + 3, save[5] = 2 * 3 = 6是最佳选择。如果按照上面代码来计算的话,就会出现
5 = 2 + 3, save[5] = 2 * save[3] = 2 * 2 = 4,结果显然是错误的。
如何解决这个问题呢?有一个办法。我们令 save[2] = 2, save[3] = 3 就好。
修改后代码如下:
int integerBreak(int n) {
int save[59];
if (n <= 3) return n-1; //n小于3直接返回
save[1] = 1; //辅助用
save[2] = 2;
save[3] = 3;
for (int i = 4; i <= n; i++){
save[i] = 0;
for (int j = 1; j < i; j++)
save[i] = max(save[i], (i-j) * save[j]);
}
return save[n];
}
当然这样做之后结果是正确的,但是效率较低,时间复杂度为O(n^2),没有更好的办法呢?
我们通过观察答案了解到,实际上所有的数,经过最佳拆分之后,拆分出的数要么是2,要么是3,要么是4
就是说,所有数的最佳拆分,都是由2、3、4组成的
那么我们第二个迭代就可以修改
for (int j = 2; j <= 4 && j < i; j++)
save[i] = max(save[i], j * save[i - j]);
如此一来,时间复杂度就变为O(n)
- Leetcode 343. Integer Break
- [LeetCode] 343. Integer Break
- leetcode 343. Integer Break
- LeetCode-343. Integer Break
- LeetCode 343. Integer Break
- 343. Integer Break
- 343. Integer Break 【M】
- 343. Integer Break
- leetcode 343. Integer Break
- 343. Integer Break
- 343. Integer Break
- Leetcode:343. Integer Break
- 343. Integer Break
- LeetCode 343. Integer Break
- 343. Integer Break
- leetcode-343. Integer Break
- LeetCode: 343. Integer Break
- 343. Integer Break
- oj 对称三位数素数
- 约瑟夫环
- java notify,wait,notifyAll理解和实例(一)
- lesson7.1,7.2File类和RandomAccessFile类
- node js 安装 测试
- 343. Integer Break
- java类方法继承为什么其修饰词的范围不能越来越小
- 404 page容错页面
- QT5-msvc2015 实例之计算器
- url 中提取数据
- mysql 常用sql语句
- ToolBar+Listview+EditText,类似微信聊天页面软键盘弹出问题
- oj 1608: 1!到n!的和(递归)
- 混合模式程序集是针对“v2.0.50727”版的运行时生成的,在没有配置其他信息的情况下,无法在 4.0 运行时中加载该程序集。