lable:dp、數學方法
給定乙個正整數 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就可以,遍歷dp[i]*dp[j-i]得到max,即為所求,狀態轉移方程:
d p[
i]=m
ax(m
ax(d
p[j]
,j)∗
max(
dp[i
−j],
i−j)
)whe
re
1<=j
<=n
/2
dp[i]=max(max(dp[j],j)*max(dp[i-j],i-j)) \ where \ 1<=j <= n/2
dp[i]=
max(
max(
dp[j
],j)
∗max
(dp[
i−j]
,i−j
))wh
ere1
<=j
<=n
/2此外,有人看出規律,可以o(n)解決,從7往後都是 dp[n]=dp[n-3]*dp[3]
當然也可以用數學方法,把乙個數分成兩個數,當這兩個數最接近時,乘積最大,那麼三個數呢,四個數呢,可以發現當劃分成所有的數最接近時數最大,也就是:
y =(
n/x)
xy=(n/x)^x
y=(n/x
)x當x=e時,y最大,因為整數所以,x=2或3,而6是2和3的最小公倍數,只要涉及2、3的都可以根據6來判斷,6=2+2+2=3+3,8<9,所以應盡可能分配3,剩下的用2。這也是dp簡化法的原因。
3 n/
3>2n
/2
3^>2^
3n/3
>2n
/2dp:
數學方法:package main
import
"fmt"
/*執行用時 :0 ms, 在所有 go 提交中擊敗了100.00%的使用者
記憶體消耗 :2 mb, 在所有 go 提交中擊敗了10.00%的使用者
*/func
max(i,j int
)int
else
}func
integerbreak
(n int
)int}}
return dp[n]
}func
main()
for_
,v:=
range tables
}
func
integerbreak
(n int
)int
if n==
3 ret:=
1for n>
4return ret*n
}
343 整數拆分
題目鏈結 首先根據題目很容易的到的乙個點是 要使乘積最大能選擇的 數字只能是1 2 3 之後選擇的任何乙個數都可以拆分成這三個的乘積所以只要選這三個就可以。證明方法就是 假設輸入的數為x在x 4 的時候 2 x 2 x恆成立因此在選擇 乘積大於4的時候總是能選擇乙個 x 和 x 2 拆分這個資料 如...
343 整數拆分
給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。示例 1 輸入 2 輸出 1 解釋 2 1 1,1 1 1。示例 2 輸入 10 輸出 36 解釋 10 3 3 4,3 3 4 36。說明 你可以假設 n 不小於 2 且不大於 58。求最值問題最...
343 整數拆分
給定乙個正整數 n,將其拆分為至少兩個正整數的和,並使這些整數的乘積最大化。返回你可以獲得的最大乘積。令dp i 表示正整數i拆分時獲得的最大乘積,那麼i可以拆分為j和i j,如果i j不在拆分,乘積就是j i j 如果繼續拆分,乘積就是j dp i j 遍歷j取最大值即可。邊界條件,dp 0 dp...