例1.整數劃分問題
將正整數n表示成一系列正整數之和。
如 p(6)有11種劃分:
6;5 + 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;
從上述可以看出 :
1>對於p(6)來說,其都是不大於6的數字進行相加得到。
2>以5開頭的有1條資料,以4開頭的有2條,以3開頭的有3條...,所以得到以m開頭的就有6-m條;除了全部是1組成的資料。
假設我們將 n 代替 6,在正整數n的所有不同的劃分中,將最大正整數n1不大於m的劃分個數記為p(n, m);
對於6來說即為p(6, 6);
此時我們只需要確定n,m之間的區域規則劃分即可。
1.當n = 1時或者m = 1時只有 p(n, m) = 1;
2.當m > n 時,p(n, m) = p(n , n);
3.當m = n 時 p(n, m) = 1 + p(n, n - 1);
4.當n > m > 1 時 p(n, m) = p(n, m - 1) + p(n - m, m);
對於第一點來說 指的就是1 + 1 + 1 + ...的情況。
對於第二點來說,因為不會存大於n的m組成的正整數之和為n;
對於第三點來說,指的是自身n的這一條資料加上p(n, n - 1)的情況
對於第四條來說,假設 n = 6, m = 4;則p(6, 4) = p(6, 3) + p(2, 4),我們可以看到p(6,3)是指m最大為3的所有資料劃分,對於p(6,4)就只剩下了含有最大數為4的劃分。
此時我們思考乙個問題,一定含有4且4一定是小於6的,與4組成的資料劃分之和為6,也就是說其他資料之和最大為6 - 4 = 2;
對於求含有4的劃分資料之和可以轉變為求所有之和為2的資料劃分,即p(n - m, m)。所以p(n, m) = p(n, n - 1) + p(n - m, m);
所以我們可以得到以下的遞迴式:
//整數劃分問題private
int q(int n, int
m)
if (n == 1 || m == 1)
if (n
if (n ==m)
return q(n, m - 1) + q(n -m , m);
}
分治與遞迴
分治與遞迴 分治法的設計思想是,將乙個難以直接解決的大問題,分割成一些規模較小的相同問題,以便各個擊破,分而治之。對這k個子問題分別求解。如果子問題的規模仍然不夠小,則再劃分為k個子問題,如此遞迴的進行下去,直到問題規模足夠小,很容易求出其解為止。將求出的小規模的問題的解合併為乙個更大規模的問題的解...
遞迴與分治
一 1 求階乘 int factorial int n 2 fibonacci函式 int fibonacci int n 3 全排列 1 字串的全排列 主函式見 2 int permutation char a,int k,int m permutation arr,0,n 1 return 0 ...
遞迴與分治
fibonacci數列 無窮數列1,1,2,3,5,8,13,21,34,55,稱為fibonacci數列。它可以遞迴地定義為 第n個fibonacci數可遞迴地計算如下 int fibonacci int n 編寫完整的主函式,分別記錄利用上述遞迴函式求第47,48,49,50,51,52個fib...