7215 簡單的整數劃分問題

2022-09-11 10:42:14 字數 3334 閱讀 5283

簡介: 總時間限制: 100ms 記憶體限制: 65536kb描述將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。正整數n 的這種表示稱為正整數n 的劃分。

總時間限制: 100ms 記憶體限制: 65536kb

描述將正整數n 表示成一系列正整數之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。

正整數n 的這種表示稱為正整數n 的劃分。正整數n 的不同的劃分個數稱為正整數n 的劃分數。

輸入標準的輸入包含若干組測試資料。每組測試資料是乙個整數n(0 < n <= 50)。

輸出對於每組測試資料,輸出n的劃分數。

樣例輸入

5樣例輸出7提示

5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1

注意對比題目:

(1)數的劃分(把n分為k份,有點類似於放蘋果,但放蘋果這道題目裡面盤子可以為空,它不允許為空。)

(2)複雜的整數劃分 

演算法(一)遞迴法

把乙個正整數n寫成如下形式: n=m1+m2+...+mi; (其中mi為正整數,並且1 <= mi <= n),則為n的乙個劃分。如果中的最大值不超過m,即max(m1,m2,...,mi)<=m,則稱它屬於n的乙個m劃分。這裡我們記n的m劃分的個數為f(n,m);

例如當n=4時,他有5個劃分,,,,,;注意4=1+3 和 4=3+1被認為是同乙個劃分。

根據n和m的關係,考慮以下幾種情況:

(1)當n=1時,不論m的值為多少(m>0),只有一種劃分即;

(2) 當m=1時,不論n的值為多少,只有一種劃分即n個1,;

(3) 當n=m時,根據劃分中是否包含n,可以分為兩種情況:

(a). 劃分中包含n的情況,只有乙個即;

(b). 劃分中不包含n的情況,這時劃分中最大的數字也一定比n小,即n的所有(n-1)劃分。因此 f(n,n) =1 + f(n,n-1);

(4) 當nm時,根據劃分中是否包含最大值m,可以分為兩種情況:

(a). 劃分中包含m的情況,即}, 其中 的和為n-m,可能再次出現m,因此是(n-m)的m劃分,因此這種劃分個數為f(n-m, m);

(b). 劃分中不包含m的情況,則劃分中所有值都比m小,即n的(m-1)劃分,個數為f(n,m-1);因此 f(n, m) = f(n-m, m)+f(n,m-1);

綜合以上情況,我們可以看出,上面的結論具有遞迴定義特徵,其中(1)和(2)屬於回歸條件,(3)和(4)屬於特殊情況,將會轉換為情況(5)。而情況(5)為通用情況,屬於遞推的方法,其本質主要是通過減小m以達到回歸條件,從而解決問題。其遞推表示式如下:

f(n, m)    =1;            (n=1 or m=1)

=f(n, n);          (nm)

1 #include 2 long long getpartitioncount(int n,int max)

3

24 if (j > root)

25 primes.push_back(i);

26 }

27 }

28

29 // 輸出所有素數組合(遞迴實現)

30 int printcombinations(int num, const vector&primes, int from, vector&numbers)

31

39

40 int count = 0;

41

42 // 從第from個素數搜尋,從而避免輸出同構的多個組合

43 int primesnum = primes.size();

44 for (int i = from; i < primesnum; ++i)

45

52

53 return count;

54 }

55

56 // 計算num的所有素數和分解

57 int expandedgoldbach(int num)

58

68

69 int main()

70

77 }

view code

c語言**如下:

1 #include2 #include3 #include4 

5 #define maxnum 1000

6 int primenum[maxnum]=,ansarr[maxnum]=;

7 int indexforprimenum,indexforansarr;

8 9 int work(int num);//輸出num的所有素數和分解的方案並返回其總方案數

10 int calcprimes(int num);//計算num內的所有素數(不包括num),結果儲存在primenum.

11 12 int printans(int num,int from);

13 //回溯法的思想:從primenum的第from個元素開始選擇元素來累加構造num。

14 //構造結果放在ansarr中。尋找到乙個構造方案後輸出該方案.

15 //最終返回總的方案數

16 17 int main(int argc, char *ar**)

18 25 return 0;

26 }

27 //計算num內的所有素數(不包括num),結果儲存在primenum. 返回陣列元素個數

28 int calcprimes(int num)

29 45 return k;

46 }

47 //呼叫printans()輸出num的所有素數和分解的方案,返回其總方案數

48 int work(int num)

49 58

59 //回溯法的思想:從primenum的第from個元素開始選擇元素來累加構造num。

60 //構造結果放在ansarr中。尋找到乙個構造方案後輸出該方案.

61 //最終返回總的方案數

62 int printans(int num,int from)

63 {

64 int i;

65 if(num==0)

66 {

67 printf("found: ");

68 for(i=0;iview code

參考:

簡單整數劃分問題

1.純遞迴 設函式func int n,int m 定義為計算 把整數 n 劃分為 小於或等於 m 的一系列數字之和 的劃分方法有多少種,則對於 1 當 n 1 時,無論 m 取何值,都只能 劃分為 1 2 當 m 1 時 無論 n 為何值,也只能劃分為 n 個 1 相加 只有一種劃分方法 3 當 ...

簡單的整數劃分問題

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

遞迴 OpenJudge 7215 簡單整數劃分

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