您的位置:首页 > 其它

Leetcode 343. Integer Break

2016-04-19 23:03 176 查看
原题链接:

343. Integer Break


343. Integer Break

My Submissions

Question
Editorial Solution

Total Accepted: 642 Total
Submissions: 1506 Difficulty: Medium

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.
Hint:

There is a simple O(n) solution to this problem.
You may check the breaking results of n ranging from 7 to 10 to discover the regularities.

Credits:

Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

Hide Tags
Dynamic Programming Math

思路:

乍一看,很明显的一道动态规划题目,而且很容易想到的是O(n^2)的解法。

解法一:DP O(n^2)解法

int integerBreak(int n) {
vector<int> dp(n + 1, 1);

for(int i = 1; i <= n; ++i)
{
for(int j = 1; j <= i + 1; ++j)
{
if(i + j <= n)
{
dp[i + j] = max(max(dp[i], i) * max(dp[j], j), dp[i + j]);
}
}
}

return dp
;
}


恩,Hint提示说有O(n)的解法,让我们从7-10这些数的结果中找规律。
n = 2 max = 1(1 + 1)

n = 3 max = 2(1 + 2)

n = 4 max = 4(2 + 2)

n = 5 max = 6(2 + 3)

n = 6 max = 9(3 + 3)

n = 7 max = 12(3 + 2 + 2)

n = 8 max = 16(2 + 2 + 2 + 2)

n = 9 max = 27(3 + 3 + 3)

n = 10 max = 36(2 + 2 + 3 + 3)

大致也发现了一点规律,我们都分解为1 2 3这样的组合。

很简单,如果组合为4,4又可以分解为2 + 2,如果组合为5,5又可以分解为2 + 3。

以此类推~

上面还有一个规律,如果一个数分解后可以写成全是2或全是3,那么全是3的乘积肯定比全是2的大。

比如6 = 2 + 2 + 2 = 3 + 3 肯定是3*3 > 2*2*2。

所以基于上面的思路,可以写出O(n)的代码了:

int integerBreak(int n) {
if(n <= 3) return n - 1;

vector<int> dp(n + 1, 0);
dp[1] = 1;
dp[2] = 2;
dp[3] = 3;

for(int i = 4; i <= n; ++i)
{
dp[i] = max(2 * dp[ i - 2], 3 * dp[i - 3]);
}

return dp
;
}


下面写点数学公式:

对于n≥4

n = 4 max = 4

n > 4 下面这个等式肯定是正确的。

3 * (n - 3) > n

上面这个式子说明:将n分解为3 和 n - 3,乘积变大了,对不对。

【不要问我为什么分解为3和n-3

上面分解为2的乘积比分解为3乘积小,系不系?

如果能分解为3,何乐不为呢?

大致这么解释吧~】

继续n-3,按照上面这个规律分解下去。

恩,第二种解法出来了~

解法二:递归

int integerBreak(int n) {
int a[5] = {1, 2, 4, 6, 9};

if(n <= 6) return a[n - 2];
else return 3 * integerBreak(n - 3);
}


OK,上面这个思路转化下,其实就是能分解为3,就尽可能分解为3,
分为下面几种情况:

n % 3 == 0 就全部分解为3。

n % 3 == 1 肯定有个4,剩下的分解为3。

n % 3 == 2 有个2,剩下的全部分解为3。

所以,代码也可以这么写~

int integerBreak(int n) {
if(n <= 3) return n - 1;
if(n % 3 == 0) return pow(3, n / 3);
if(n % 3 == 1) return 4 * pow(3, (n - 4) / 3);
if(n % 3 == 2) return 2 * pow(3, n / 3);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: