算法作业-整数划分-动态规划

正整数的划分问题是将一个正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。请编写至少三种不同的求解算法,并对所编写算法的时间效率进行测试和比较。

解法一:递归算法

解法二:动态规划算法

算法如下:

Java代码如下:

package integer_division;

public class Integer_division_2 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		long startTime = System.currentTimeMillis();
		System.out.println(p1(100));//打印100的划分种类数
		long endTime = System.currentTimeMillis();
		System.out.println("程序运行时间:"+(endTime - startTime) + "ms");
	}

	public static int p1(int n) {
		// TODO Auto-generated method stub
	    int[][] q =  new int[n+1][n+1];
	    int  i, j;
	    for (i=1; i<=n; i++){
	    	q[1][i]=q[i][1]=1;
	    }
	    for (i=2; i<=n; i++){
	    	for (j=2; j<=n; j++){
	    		if (i<j){
	    			q[i][j]=q[i][i];
	    		}
	    		else if(i==j){
	    			q[i][j]=1+q[i][j-1];
	    		}
	    		else{
	    			q[i][j] = q[i][j-1]+q[i-j][j];
	    		}
	    	}
	    }
	    return q[n][n];
	}
	//p2与p1相比,少占用了2n+1的空间,方法一样
	public static int p2(int n) {
		// TODO Auto-generated method stub
	    int[][] q =  new int[n][n];
	    int  i, j;
	    for (i=0; i<n; i++){
	    	q[0][i]=q[i][0]=1;
	    }
	    for (i=1; i<n; i++){
	    	for (j=1; j<n; j++){
	    		if (i<j){
	    			q[i][j]=q[i][i];
	    		}
	    		else if(i==j){
	    			q[i][j]=1+q[i][j-1];
	    		}
	    		else{
	    			q[i][j] = q[i][j-1]+q[i-j-1][j];//q[i-j-1]是为了与p1中对应的数位置保持一致
	    		}
	    	}
	    }
	    return q[n-1][n-1];
	}

}

对代码进行实例测试的结果如下:((a,b,c)中a表示正整数,b表示划分结果个数,c表示程序的运行时间,单位是毫秒)

(10,42,1)

(30,5604,1)

(50,204226,1)

(70,4087968,1)

(80,15796476,1)

(90,56634173,1)

(100,190569292,1)

(110,607163746,1)

(后面的测试实例划分结果数目过多,故不展示划分结果数目)

(200,-,2)

(300,-,3)

(400,-,4)

(600,-,6)

(800,-,9)

(1000,-,12)

(1200,-,16)


该算法的时间复杂度为O(n2)。

解法三:母函数算法

猜你喜欢

转载自blog.csdn.net/qq_36309480/article/details/80547008