整數劃分問題(二)

2022-04-05 16:32:44 字數 1875 閱讀 8451

總時間限制:

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

樣例輸出

2

33

提示第一行: 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種。下面介紹一種通過遞迴方法得到乙...