整數拆分 動態規劃法

2021-10-07 16:07:15 字數 1033 閱讀 7007

題目:

將正整數n無序拆分成最大數為m的拆分方案個數,要求所有拆分方案不重複。

例如n = 5, m = 5,對應的拆分方案如下:

5 = 5

5 = 4 + 1

5 = 3 + 2

5 = 3 + 1 + 1

5 = 2 + 2 + 1

5 = 2 + 1 + 1 + 1

5 = 1 + 1 + 1 + 1 + 1

思路:由例題可知,順序不影響結果,我們採用動態規劃法來解決問題。建立陣列dp[n+1][m+1].其中dp[i][j]指正整數i被拆分為最多j個數字的方案數。注意不是一定要拆為j個而是拆為1~j個。下面進行分析

1.當j=1 或者i=1,此時意為把數字1拆為n分,或者把數字n拆為1分。結果都是1

2.當i小於j, 此時由於拆分結果每個數字都要大於0,因此多餘的j沒用。此時dp[i][j]=dp[i][i]

3.當i=j,這裡我們把1~j拆分,分為1到j-1和j。意思就是把i拆分為j份分為1.拆成最多j-1份2.一定拆成j份。那麼容易明白前者為dp[i][j-1],後者為1,因為i=j. 此時dp[i][j]=1+dp[i][j-1]

4.當i>j,此時與第三條類似,我們同樣把1~j拆分,分為1到j-1和j。前者為dp[i][j-1]。後者繼續分析,此時i>j,又必須分為j份,那麼我們可以首先分為j份1,此時的和為j,剩下還有數字i-j,我們把剩下的數字i-j隨機分到j份中即為結果。dp[i][j]=dp[i-j][j]+dp[i][j-1]

比如求dp[5][4],首先dp[5][3]=5,然後把5分為4份,我們先給每份乙個1,此時還剩下1,把一分為最多4份即dp[1][4],其結果是1(因為不考慮順序).

public

class

solution

else

if(i == j)

else

if(i < j)

else}}

return dp[n]

[m];

}}

動態規劃法

在學習動態規劃法之前,我們先來了解動態規劃的幾個概念 1 階段 把問題分成幾個相互聯絡的有順序的幾個環節,這些環節即稱為階段。2 狀態 某一階段的出發位置稱為狀態。3 決策 從某階段的乙個狀態演變到下乙個階段某狀態的選擇。4 狀態轉移方程 前一階段的終點就是後一階段的起點,前一階段的決策選擇匯出了後...

動態規劃法

有些問題在分解時會產生許多子問題,且分解出的自問題互相交織,因而在解這類問題時,將可能重複多次解乙個子問題。這種重複當然是不必要的,解決方法可以在解決每個子問題後把它的解 包括其子子問題的解 保留在乙個 中,若遇到求與之相同的子問題時,dp演算法又稱動態規劃,是資訊學競賽中選手必須熟練掌握的一種演算...

動態規劃法

最近遇到了一道挺有意思的演算法題 四種硬幣 1元3元4元5元 問 想要湊成n元錢最少幾枚硬幣?public class coinsgamemain fun 7,is public static void fun int k,int is i1 l min i2 if l k private stat...