演算法思路:
n = n1 + n2 + n3 + n4 + .... + nk
(n1>=n2>=n3>=....>=nk),從大到小排列後,可以避免陷入數值大小排序順序的困境中。這樣,在下面的過程,我們可以並不關心數值大小的排列,只關心組合方案數。
狀態表示:將最大加數n1不大於m的劃分個數記作q(n,m)
狀態轉移:
(1) q(n,1) = 1,n>=1
當最大加數n1不大於1時,任何正整數n只有一種劃分方式,即 n = 1+1+1+..+1 (n個1相加)。
(2)q(n,m) = q(n,n),m>n
最大加數n1實際上不能大於n。因此q(1,m)=1。
(3)q(n,n) = 1+q(n,n-1)
正整數n的劃分由n1=n的劃分和n1<=n-1的劃分組成。
(4)q(n,m) = q(n,m-1) + q(n-m,m),n>m>1
正整數n的最大加數n1不大於m的劃分由n1=m的劃分和n1<=m-1的劃分組成。
另乙個思路有點相似的問題:
1-100中,
求:5個不同數的和小於100的不重複組合的個數.
設立乙個陣列a[5][100][100]
a[i][j][k]表示用i個[j, 100]之間的不同的數,最小數為j且和小於k的組合有多少種
//假設陣列下標從1開始
則有a[i][j][k] = sigma m屬於[j+1, k]
e.g.
a[5][1][100]
表示所求組合中,最小的那個數為1的情況
那麼其餘四個數中最小的至少是2,並且那四個數和小於99
所以a[5][1][100] = a[4][2][99] + a[4][3][99] + ...
整數劃分問題 動態規劃
原文出處 整數劃分 有以下情況 1 將n劃分成若干正整數之和的劃分數。2 將n劃分成k個正整數之和的劃分數。3 將n劃分成最大數不超過k的劃分數。4 將n劃分成若干奇正整數之和的劃分數。5 將n劃分成若干不同整數之和的劃分數。include includeconst int ns 55 int n,...
DP 動態規劃 整數劃分
時間限制 3000 ms 記憶體限制 65535 kb 難度 3 輸入第一行是測試資料的數目m 1 m 10 以下每行均包含乙個整數n 1 n 10 輸出輸出每組測試資料有多少種分法。描述將正整數n表示成一系列正整數之和 n n1 n2 nk,其中n1 n2 nk 1,k 1。正整數n的這種表示稱為...
整數劃分 劃分數(DP動態規劃)
給你乙個正整數n,讓你計算出n的m劃分有幾種方法。思路 定義dp i j 為i的j劃分,即將i劃分為j個數字之和的方案數。1 當j i時,此時,劃分個數不超過i,此時是正常的劃分。劃分的結果一定只有兩種型別 一種是j個數字,都大於0。另一種是有0,即不夠劃分j個,用0來湊的。j個數字中存在0的,其實...