前往
大廳
主題

LeetCode - 343. Integer Break 解題心得

Not In My Back Yard | 2022-07-12 12:00:05 | 巴幣 0 | 人氣 322

題目連結:


題目意譯:
給定一整數 n,將其分解成 k 個正整數之總和,其中 k ≧ 2,並使這些整數之乘積最大化。

回傳你可以得到的最大乘積值。

限制:
2 ≦ n ≦ 58



範例測資:
範例 1:
輸入: n = 2
輸出: 1
解釋: 2 = 1 + 1,1 × 1 = 1.

範例 2:
輸入: n = 10
輸出: 36
解釋: 10 = 3 + 3 + 4,3 × 3 × 4 = 36.


解題思維:
雖然這題可以用一般的動態規劃(Dynamic Programming)的精神解開——即已知 j = 1 ~ n - 1 的最佳分解法(稱其為 D[j]),則可以藉由窮舉 j 來找出哪個 j 值最大化 D[j] × D[n - j],而這便是 D[n] 之值。



但是我們可以有更好的作法(至少可以減少窮舉不必要的 j 值):
首先我們可以先問自己:「最大乘積裡面真的會出現 ≧ 5 的數字嗎?」

答案是:「不會。」原因很簡單,先看一下「5」這個數字,將其拆成「3 + 2」便可以得到 3 × 2,而可以看到這個數字會大於 5。而 > 6 的數字都可以直接無腦拆成若干個 3 和 2 便可以得到更大的乘積值。因此分解後的乘積值必定不會出現 5 以上(含)的數字。

而「4」不管是維持 4 本身或是拆成兩個 2,乘積值都是 4。而這邊為了方便起見,統一拆成兩個 2。

因此可以看到對於任意 n 值,我們的最大乘積之中只會出現 2 或是 3。那選 3 還是選 2 比較好呢?觀察 n = 6 時,3 + 3 和 2 + 2 + 2 都是 6 的一種分解法,但是可以看到 3 + 3 得到的乘積值 3 × 3 = 9 會大過 2 + 2 + 2 的乘積值 2 × 2 × 2 = 8。

所以可以看到我們應盡量選 3 才會使乘積值最大化。

不過今天我們先著重於動態規劃解法的最佳化——根據上面前半部的結論,我們窮舉 j 值的時候只需要窮舉 j = 2 、 3 的情況。

至於後半部的結論之用處則留給明天的問題




此次分享到此為止,如有任何更加簡潔的想法或是有說明不清楚之地方,也煩請各位大大撥冗討論。

創作回應

更多創作