整數劃分問題 經典DP

2021-08-17 19:30:29 字數 2668 閱讀 4995

相關題目1

相關題目2

相關題目3

下面的描述大部分借鑑於( 感謝, 但是其中有部分錯誤, 我會在下面的描述中糾正過來…

總的解決方法時截邊法, 也就是去討論有1無1的情況和截去他們的情況….. 記住了.

1. 若劃分的多個整數可以相同

設dp[i][j]為將i劃分為不大於j的劃分數

(1) 當i < j 時,i不能劃分為大於i的數,所以dp[i][j]=dp[i][i];

(2) 當i>j 時,可以根據劃分中是否含有j分為兩種情況。若劃分中含有j,劃分方案數為dp[i-j][j];若劃分數中不含j,相當於將i劃分為不大於j-1的劃分數,為dp[i][j-1]。所以當i>j時dp[i][j]=dp[i-j][j]+dp[i][j-1];

(3) 當i=j 時,若劃分中含有j只有一種情況,若劃分中不含j相當於將i劃分為不大於j-1的劃分數。此時dp[i][j]=1+dp[i][j-1]

2. 若劃分的正整數必須不同

設dp[i][j]為將i劃分為不超過j的不同整數的劃分數

(1) 當i< j時,i不能劃分為大於i的數,所以dp[i][j]=dp[i][i];

(2) 當i>j時,可以根據劃分中是否含有j分為兩種情況。若劃分中含有j,則其餘的劃分中最大只能是j-1,方案數為dp[i-j][j-1];若劃分中不含j,相當於將i劃分為不大於j-1的劃分數,為dp[i][j-1]。所以當i>j時dp[i][j]=dp[i-j][j-1]+dp[i][j-1];(與上面的的轉移方程唯一不同的地方, dp[i-j][j-1])

(3) 當i=j時,若劃分中含有j只有一種情況,若劃分中不含j相當於將i劃分為不大於j-1的劃分數。此時dp[i][j]=1+dp[i][j-1]

dp[n][n]表示將n劃分為不同整數的劃分數

設dp[i][j]為將i恰好劃分為j個整數的劃分數 (解答描述已糾正)

(1) i< j為不可能出現的情況,dp[i][j]=0;

(2) 若i=j,有一種情況:i可以劃分為i個1之和,dp[i][j]=1;

(3) 若i>j,可以根據劃分數中是否含有1分為兩類:若劃分數中含有1,可以使用「截邊法」將1截去,把問題轉化求i-1的j-1個劃分數,為dp[i-1][j-1]; 若劃分中不包含1,使用「截邊法」將j個劃分數每個都截去乙個1將問題題轉化為求i-j的j個劃分數,為dp[i-j][j]。所以i>j時 dp[i][j] = dp[i-1][j-1]+dp[i-j][j].

設f[i][j]為將i恰好劃分為j個奇數之和的劃分數,g[i][j]為將i恰好劃分為j個偶數之和的劃分數

使用截邊法,將g[i][j]的j個劃分都去掉1,可以得到f[i-j][j],所以

g[i][j] = f[i-j][j] (因為總的考慮1的情況, 所以注重討論奇數的情況)

f[i][j]中有包含1的劃分方案和不包含1的劃分方案。對於包含1的劃分方案,可以將1的劃分除去,轉化為「將i-1劃分為j-1個奇數之和的劃分數」,即f[i-1][j-1];對於不包含1的劃分方案,可以使用截邊法對j個劃分每乙個都去掉乙個1,轉化為「將i-j劃分為j個偶數之和的劃分數」,即g[i-j][j]。

所以f[i][j]=f[i-1][j-1]+g[i-j][j]。

f[n][0]+f[n][1]+……+f[n][n]為將n劃分為若干奇數的劃分數的方案數.

設dp[i][j] 代表 i 劃分為不多於j個正整數的劃分數

所以:

(1) 當 i == 1 || j == 1時, dp[i][j] = 1; 前面為只有1這個情況, 後面為劃分為自身的情況.

(2) 當 i == j 時, dp[i][j] = dp[i][j-1] + 1; 表示將i劃分為不多於j-1個的方案數, + 全是1組成i的情況.

(3) 當 i < j 時, 沒有多餘方案, dp[i][j] = dp[i][i];

(4) 當 i > j 時, 分兩種齊情況, 一是如果這不多於j個正整數中有1,那麼可以將這個1合併到任意乙個數字中, 也就是求i 劃分為不多於j-1個正整數的方案, 而是如果 這不多於j個正整數中沒有1, 那麼可以利用截邊法將每乙個數字截去1, 那麼就是求截去1的方案數也就是dp[i-j][j]; 所以轉移方程為:

dp[i][j] = dp[i][j-1] + dp[i-j][j];

下面就是上面這些所有的問題解決模板了: 需要哪個用哪個. 唯一坑點就是可能資料量較大 , 需要long long.

ll dp[maxn][maxn];

ll f[maxn][maxn], g[maxn][maxn];

int n, k;

void div1()

}}void div2()

else

if (i == j) dp[i][j] = dp[i][j-1] + 1;

else

if (i < j) dp[i][j] = dp[i][i];

else dp[i][j] = dp[i][j-1] + dp[i-j][j-1];}}

}void div3()

}}void div4() }}

}void div5()

}}

**都是可以通過上面的問題的….. 所以下次遇到了直接取就行……

OJ演練 整數劃分(經典DP問題)

對整數劃分,關鍵點 1 找出動態規劃的狀態轉移方程 2 確定各種情況下的初始條件 description 將正整數n表示成一系列正整數之和 n n1 n2 nk,其中n1 n2 nk 1。正整數n的這種表示稱為正整數n的劃分。求正整數n的不同劃分個數。例如,正整數6有如下11種不同的劃分 6 6 5...

整數劃分問題 DP

整數劃分的定義 n m1 m2 mi 其中mi為正整數,並且1 mi n 則為n的乙個劃分。如果中的最大值不超過m,即max m1,m2,mi m,則稱它屬於n的乙個m劃分。這裡我們記n的m劃分的個數為f n,m 舉個例子,當n 5時我們可以獲得以下這幾種劃分 注意,例子中m 5 5 5 4 1 3...

百練 簡單的整數劃分問題(經典dp)

04 簡單的整數劃分問題 總時間限制 100ms 記憶體限制 65536kb 描述 將正整數n 表示成一系列正整數之和,n n1 n2 nk,其中n1 n2 nk 1 k 1 正整數n 的這種表示稱為正整數n 的劃分。正整數n 的不同的劃分個數稱為正整數n 的劃分數。輸入 標準的輸入包含若干組測試資...