簡介: 總時間限制: 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)view code3
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 }
c語言**如下:
1 #include2 #include3 #include45 #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 的劃分數。輸入標準的輸入包含若干組測試資料。每組...