劍指Offer對答如流系列 剪繩子

2022-08-30 02:30:14 字數 1603 閱讀 4173

給你一根長度為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。

遇到問題,先分析問題,由分析的結果確定所運用的演算法。

一般而言,我們都會在紙上動筆畫畫,羅列一些基本的情況。

題中說n>1並且m>1,那麼

參考n= x的情況,如果把長度n繩子的最大乘積記為f(n),則有:f(n)=max(f(i)*f(n-i)),0當你分析到這個的時候,思路就得到了一層的突破:從下往上推,先算小的問題,再算大的問題,大的問題通過尋找小問題的最優組合得到。這個不就是動態規劃嗎?

動態規劃演算法的定義是通過拆分問題,定義問題狀態和狀態之間的關係,使得問題能夠以遞推(或者說分治)的方式去解決。

既然寫到了動態規劃,那我就將我所知道的都告訴你:

關於動態規劃演算法定義的理解

至於演算法思想的理解,我們解答中**

這個涉及到乙個數學模型,原本的定義非常巨集大和複雜,這裡不多贅述,我們這裡只是涉及到一丁點的應用,你有個印象即可。

我們之前也討論了,剛才的遞推式f(n)=max(f(i)*f(n-i)),0對於任意乙個大於或者等於5的數字,都可分解為加數 2 和 3的和。(這個小學數學就能證明,不證明了哈)

遞推式涉及到乘積,很容易注意且能證明3(length-3)>2(length-2),因此要想乘積最大,盡可能分出更多的加數3

除了上述所說的,我們還有乙個特殊的數字就是4,當length=4的時候,13<22=4,所以length=4的時候不用再分。

區域性最優能保證整體最優,貪心演算法寫起來要比動態規劃簡單多了。

/**

* @param length 輸入的繩子的長度

* @return 乘積的最大值

* 動態規劃的演算法思想:

* 動態規劃演算法的基本思想與分治法類似,也是將待求解的問題分解為若干個子問題(階段),按順序求解子階段,前一子問題的解,為後一子問題的求解提供了有用的資訊。

* 在求解任一子問題時,列出各種可能的區域性解,通過決策保留那些有可能達到最優的區域性解,丟棄其他區域性解。依次解決各子問題,最後乙個子問題就是初始問題的解。

*/public int maxproductaftercutting(int length)

// 把最優解儲存下來(為了後面的使用的最優解,為區域性最優解)

product[n] = max;

}return product[length];

}

public int maxproductaftercutting(int length) 

int timesoftwo = (length - timesofthree * 3) / 2;

return (int) (math.pow(3, timesofthree) * math.pow(2, timesoftwo));

}

劍指Offer對答如流系列 醜數

我們把只包含質因子2 3和5的數稱作醜數 ugly number 求按從小到大的順序的第n個醜數。例如6 8都是醜數,但14不是,因為它包含質因子7。習慣上我們把1當做是第乙個醜數。判斷乙個數是不是醜數,最容易想到的方法就是讓這個數不斷除以2,3,5。對於第n個醜數,只要從1開始,依次判斷每個數是不...

劍指Offer對答如流系列 包含min函式的棧

定義棧的資料結構,請在該型別中實現乙個能夠得到棧的最小元素的min函式。在該棧中,呼叫min push及pop的時間複雜度都是o 1 push 和 pop均容易實現。主要就是min函式的定義,如果要通過操作push和pop操作獲取最小元素時間複雜度為o 1 基本上是不可能的。如果我們另外定義乙個成員...

劍指Offer對答如流系列 樹的子結構

輸入兩棵二叉樹a和b,判斷b是不是a的子結構。二叉樹的定義如下 public class treenode 比如下面的 b是a的子結構 看了看 劍指offer 高質量 章節的面試題,發現難度都不高,但是沒有分析好邊界條件亦或是想當然就是容易出錯,細心從來不是說說而已。請重視自己 的規範性 完整性和魯...