1. 程式人生 > >演算法作業-整數劃分-遞迴

演算法作業-整數劃分-遞迴

正整數的劃分問題是將一個正整數n表示成一系列正整數之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。請編寫至少三種不同的求解演算法,並對所編寫演算法的時間效率進行測試和比較。

解法一:遞迴演算法
考慮增加一個自變數:將最大加數n1不大於m的劃分個數記作q(n,m),可以建立q(n,m)的如下遞迴關係:
1,q(n,1) = 1, n≥1; 當最大加數n1不大於1時,任何正整數n只有一種劃分形式,即n=1+1+…+1
2,q(n,m) = q(n,n), m≥n; 最大加數n1實際上不能大於n,因此,q(1,m) = 1
3,q(n,n) = 1 + q(n, n-1); 正整數n的劃分由n1 = n的劃分和n1≤n-1的劃分組成
4,q(n,m)=q(n,m-1)+q(n-m,m),n>m>1; 正整數n的最大加數n1不大於m的劃分由n1= m的劃分和n1≤m-1 的劃分組成


正整數n的劃分數p(n)=q(n,n)。

演算法如下:


Java程式碼如下:

package integer_division;

public class Integer_division_1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long startTime = System.currentTimeMillis();
		System.out.println(q(80,80));//列印80的劃分種類數
		long endTime = System.currentTimeMillis();
		System.out.println("程式執行時間:"+(endTime - startTime) + "ms");
	}

	public static int q(int n, int m) {
		// TODO Auto-generated method stub
		if ((n == 1)||(m == 1)) 
			return 1;
		if (n < m)
			return q(n,n);
		if (n == m)
			return q(n,m-1)+1;
		return q(n,m-1)+q(n-m,m);
	}

}

對程式碼進行例項測試的結果如下:((a,b,c)中a表示正整數,b表示劃分結果個數,c表示程式的執行時間,單位是毫秒)

(10,42,1)

(30,5604,1)

(50,204226,2)

(70,4087968,14)

(80,15796476,51)

(90,56634173,188)

(100,190569292,570)

(110,607163746,1873)

從程式執行結果看出遞迴演算法的時間複雜度極高,但具體的複雜度函式是什麼呢?

I don't know.

解法三:母函式演算法