總時間限制:
200ms
記憶體限制:
65536kb
描述將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整數n 的這種表示稱為正整數n 的劃分。
輸入標準的輸入包含若干組測試資料。每組測試資料是一行輸入資料,包括兩個整數n 和 k。
(0 < n <= 50, 0 < k <= n)
輸出對於每組測試資料,輸出以下三行資料:
第一行: n劃分成k個正整數之和的劃分數目
第二行: n劃分成若干個不同正整數之和的劃分數目
第三行: n劃分成若干個奇正整數之和的劃分數目
樣例輸入
5 2
樣例輸出
233
提示第一行: 4+1, 3+2,
第二行: 5,4+1,3+2
第三行: 5,1+1+3, 1+1+1+1+1+1
** openjudge
參考**及分析
/**1、n劃分成k個正整數之和的劃分數目
i:要被劃分的數,這裡假設為5;j:劃分成j個正整數,這裡假設為2;
dp[i][j]
①沒有1的情況
dp[i-j][j],因為要分成j份,所以從i中拿出j個1,把i-j分成j份,每乙個份加上1就是沒有1的情況了。
栗子:3,2;三分成兩份,1+2,每份加上1即2+3,就是沒有1的情況。
②有至少有乙個1的情況
dp[i-1][j-1],先從i中拿出1算做乙份,還剩下j-1份,把i-1分成j-1份就是有1的情況了。
栗子:4,1,4分成1份,4,再加上1的份,即4+1,就是有1的情況。
2、n劃分成若干個不同正整數之和的劃分數目
i:要被劃分的數,這裡假設為5;j:劃分數都不大於j,這裡假設為5
dp[i][j]
因為劃分數都是不同的,所以每乙個劃分數要麼有,要麼沒有所以分兩種情況
①劃分數沒有j的情況
dp[i][j-1]
②劃分數有j的情況
dp[i-j][j-1]
3、n劃分成若干個奇正整數之和的劃分數目
g[i][j]:i,被劃分的數;j,劃分成j個偶數;
f[i][j]:i,被劃分的數;j,劃分成j個奇數;
①在i中拿出j個1,將i-j分成j個奇數,將1再加上就成了j個偶數
g[i][j]=f[i-j][j];
分成奇數又成有1和沒有1的情況
①有1的情況
g[i-j][j],劃分成偶數,每個偶數減1就是劃分成奇數有1的情況
f[i-1][j-1],劃分成奇數,把1的份去掉
*/#include
#include
using
namespace
std;
intn,k;
int res1[51][51],res2[51][51],g[51][51],f[51][51
];int
res3;
void
dp();
intmain()
return0;
}void
dp()
for(int i=1;i<=n;i++)
if(iif(i>j)
}}f[
0][0]=1;//
當i=1,j=1時,f[1][1]=f[0][0]+g[i-j][j]
for (int i=1;i<=n;i++)
}cout
cout
res3=0
;for(int i=1;i<=n;i++)
cout
}
整數劃分問題
整數劃分問題是乙個經典問題,幾乎在講演算法設計的書中都會講,下面把主要的思想給總結下。所謂整數劃分,就是將乙個正整數n劃分為一系列的正整數之和,如將n可以劃分為 1 我們該如何找出所有的劃分呢?我們可以先來看看整數劃分的規律 譬如正整數 6 劃分情況如下 6 5 14 2 4 1 1 3 3 3 2...
整數劃分問題
給定乙個自然數,分成k部分,a1,a2.的數的和,要求a1 a2.求有多少種?原理 整數n拆分成最多不超過m個數的和的拆分數,和n 拆分成最大不超過m的拆分數相等。根據這個原理,原問題就轉化成了求最大拆分為k的拆分個數與最大拆分為k 1的拆分個數的差 f n,k f n,k 1 f n k,k 如下...
整數劃分問題
首先是遞迴解法 整數劃分問題是將乙個正整數n拆成一組數連加並等於n的形式,且這組數中的最大加數不大於n。如6的整數劃分為 65 1 4 2,4 1 1 3 3,3 2 1,3 1 1 1 2 2 2,2 2 1 1,2 1 1 1 1 1 1 1 1 1 1 共11種。下面介紹一種通過遞迴方法得到乙...