給你一根長度為 n 的繩子,請把繩子剪成整數長度的 m 段(m、n都是整數,n>1並且m>1),每段繩子的長度記為 k[0],k[1]…k[m] 。請問 k[0]k[1]…*k[m] 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2、3、3的三段,此時得到的最大乘積是18。
示例 1:
輸入: 2
輸出: 1
解釋: 2 = 1 + 1, 1 × 1 = 1
示例 2:
輸入: 10
輸出: 36
解釋: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
2 <= n <= 58
最開始的想法是暴力破解,每段從1cm剪到n厘公尺,後來發現太天真了,29的時候就跑不動了。
暴力破解
class
solution
public
void
cut(
int remain,
int last,
int n)
if(remain ==0)
for(
int i =
1;i <= remain;i++
)cut
(remain-i,last * i,n);}
}}
記憶法
思路:不好說清,舉個例子吧。
比如一段繩子長度為10,剪一刀可能的情況會是(1,9),(2,8),(3,7),
(4,6),(5,5),(6,4),(7,3),(8,2),(9,1),其中(1,9)和(9,1)這兩種剪法只會減
少繩子的長度,不會增加積,所以忽略。看其中一種就行,比如剪
法(2,8)的積有兩種情況,一種是8繼續剪然後算積,一種是8不剪
了,對應的就是**cut和notcut的積,二者種較大的就是該剪法的
最大值。之後還有(3,7)、(4,6)等剪法依次類推。
class
solution
public
intmycuttingrope
(int n,
int[
] memory)
if(memory[n]!=0
)int max =0;
/*從2開始時因為i等於1的話只會減少繩子的長度而不會增大乘積*/
for(
int i =
2;i < n;i++)if
(notcut > max)
}return memory[n]
= max;
}}
動態規劃:這個思想和記憶搜尋有點像,從頭開始遍歷,記錄下3、4、5、7、…n-1段的最大值,然後很容易就得到n段的值了。
比如i是10、k是2,那麼計算dp[10]用到的值有dp[10],2*(10 - 2),2*dp[10 - 2];這些值前面都算好了,就能用到,下次算dp[12]的時候就可以用到dp[10]了,依次類推。
class
solution
}return dp[n];}
}
《劍指offer》 014 剪繩子
劍指offer 目錄索引 題目 給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到最大的乘積18。前提 貪婪演算法...
劍指Offer 減繩子
減繩子 給你一根長度為n的繩子,請把繩子剪成整數長的m段 m n都是整數,n 1並且m 1,m n 每段繩子的長度記為k 1 k m 請問k 1 x.xk m 可能的最大乘積是多少?例如,當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此時得到的最大乘積是18。輸入描述 輸入乙個數n,意...
劍指offer 剪繩子
題目 給你一根長度為n繩子,請把繩子剪成m段 m n都是整數,n 1並且m 1 每段的繩子的長度記為k 0 k 1 k m k 0 k 1 k m 可能的最大乘積是多少?例如當繩子的長度是8時,我們把它剪成長度分別為2 3 3的三段,此 時得到最大的乘積18。思路 動態規劃 任何動態規劃都是由遞迴演...