給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。 返回你可以獲得的最大乘積。
示例 1:
輸入:2輸出:1解釋:2 = 1 + 1, 1 × 1 = 1。示例 2:
輸入:10輸出:36解釋:10 = 3 + 3 + 4, 3 × 3 × 4 = 36。說明:你可以假設 n 不小於 2 且不大於 58。
關鍵是找到狀態方程, 我們設定dp[i]表示整數i的最大乘積, 那麼把問題分成子問題, 我們發現dp[i] 與前面的dp[1] ~ dp[i-1]都有關係, 關係很容易找到
dp[i]
=max
(j *
(i-j)
, j * dp[i - j]
) j =1,
2 ······ i -
1
而初始條件dp[1] = 1, dp[2] = 2, dp[3] = 3
為什麼要加上 j * (i-j)的比較呢, 是為了處理dp[i] < i的情況, 例如
n=4, 那麼如果不考慮 j * (i-j), 因為dp[2] = 1 <2, 所以最終的結果為3, 但是其實把4分成2 * 2, 最終結果為4. 所以要加上 j * (i-j) 直接把i分成兩個數字i, j-i,的情況。
那麼可以由此得到第一種dp**
class solution
dp[i]
= tmp;
}return dp[n];}
};
時間複雜度為0(n^2)
有一些其他的部落格給了更加速度快的演算法, 有一種是利用數學推導, 得出要想使乘積最大, 只需要盡可能的多分成3, 其次是二
數學推導過程
由均值不等式(n個數的算術平均數大於等於它們的幾何平均數):
得:當把輸入的n拆分成幾個相等的數時它們的積最大。
那麼問題來了,拆分成幾個呢?
為了方便使用導數,我們先假設我們可以把n拆分成實數。那麼設每乙個數為x,則一共有n/x個數。
設它們的積為f(x),則f(x)=x(n/x),那麼怎麼求f(x)最大值呢?求導數!
f′(x)=(n/x2) * x(n/x) * (1-lnx)
當x=e時取極大值。
而我們題目裡規定x為整數,那麼我們只需要取的x越靠近e越好。那麼2冪運算複雜度為o(lgn),所以這個演算法複雜度為o(lgn)。
**如下
class solution
};
LeetCode 343 整數拆分
給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。例如,給定 n 2,返回1 2 1 1 給定 n 10,返回36 10 3 3 4 注意 你可以假設 n 不小於2且不大於58 class solution public int integerbr...
Leetcode 343 整數拆分
problem describe 給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。示例 1 輸入 2 輸出 1 解釋 2 1 1,1 1 1。示例 2 輸入 10 輸出 36 解釋 10 3 3 4,3 3 4 36。說明 你可以假設 n 不小於...
leetcode343 整數拆分
題目 給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。示例 示例 1 輸入 2 輸出 1 解釋 2 1 1,1 1 1。示例 2 輸入 10 輸出 36 解釋 10 3 3 4,3 3 4 36。說明 你可以假設 n 不小於 2 且不大於 58。...