演算法與思路:劃分型dp,遞推;
將整數n分成k份,且每份不能為空,任意兩份不能相同(不考慮順序)。
例如:n=7,k=3,下面三種分法被認為是相同的。
1,1,5; 1,5,1; 5,1,1;
因此將n劃分份的一種方法唯一的表示為n1+n2+……nk,其中n1<=n2<=….nk.
這樣可以形象地把n的k份劃分看作是把n塊積木堆成k列,且每列的積木塊數依次遞增,
也就是這n塊積木從左到右被堆成了「階梯狀」。比如,下圖是10的幾種劃分方法:
把上圖的三個矩形順時針旋轉90度後,如下圖:
不難發現,選轉之後的模型還是10的劃分,不過約束條件有所不同。
很明顯,由於原來是k份劃分,因此新的模型中的最大乙個元素必然是k。
而其餘的元素大小不限,但都不能大於k. n減去k後,n』=n-k, 剩下的問題就是求n』的任意劃分,
且其中每個元素都不大於k的方案總數了。
新模型中,n的k份剖分的一種分法表示為n塊積木從右到左遞增排列,其中最左列有k塊積木。
兩個模型中對n的k份剖分的每種分法表示是一一對應的,如:
10=1+2+2+5 對應 10=4+3+1+1+1
10=1+1+3+5 對應 10=4+2+2+1+1
10=1+2+3+4 對應 10=4+3+2+1
因此,求n的k份劃分的方案總數問題轉化為根據新模型將n做任意劃分,且其中最大的乙個部分恰好是k的問題。
求解這個新的模型可以用遞推的方法,用f (a,b)表示把b做任意份剖分,
其中最大的乙個部分等於a的方案總數,用g(a,b)表示把b做任意份劃分,
其中最大的乙個部分不大於a的方案總數,則有:
f (a, b) = g (a, b - a);
g(a, b) = f(1, b) + f(2, b) +...+ f(a, b);
又因為f(1,b)+
f(2,
b)+...+ f(a-1,
b)=g(a-
1,b); 所以
g(a,b)=
f(1,b)+
...+ f(a - 1,
b)+f(a,
b)= g(a - 1, b) + g(a, b - a) (1 <= i <= a - 1)
當b < a時,根據g(a
,b)的含義,g(a,b-
a)無意義。
當a = 1時,顯然 g(1,b)=
1.g(1, b) = 1
g (a - 1, b) + g(a, b - a) (b >= a)
g (a, b) = g (a - 1, b) (b < a)
最後的g (k, n - k)即為所求。
#include#includeint main()
}
wikioi 數的劃分
題目描述 description 將整數n分成k份,且每份不能為空,任意兩種劃分方案不能相同 不考慮順序 例如 n 7,k 3,下面三種劃分方案被認為是相同的。1 1 5 1 5 1 5 1 1 問有多少種不同的分法。輸入描述 input description 輸入 n,k 6 題解 f i,j ...
wikioi 數的劃分
劃分型dp。最終的思路是,f i j 表示i分成j份,如果分出來的有1,那麼去掉1,就是f i 1 j 1 如果沒有1,那就都減1,就是f i j j 注意此時i 2j 那麼f i j f i 1 j 1 f i j j 詳細些的話,以sample為例 7 5 1 1 7 2 4 1 7 3 3 1...
1039 數的劃分
題目描述 description 將整數n分成k份,且每份不能為空,任意兩種劃分方案不能相同 不考慮順序 例如 n 7,k 3,下面三種劃分方案被認為是相同的。1 1 5 1 5 1 5 1 1 問有多少種不同的分法。輸入描述 input description 輸入 n,k 6輸出描述 outpu...