代码改变世界

递归分治算法求解--整数划分问题

2011-08-27 19:03  Rollen Holt  阅读(4260)  评论(0编辑  收藏  举报

【问题描述】:

将正整数n表示为一系列整数的和:

n=N1+N2+N3+…Nn  其中(N1>=N2>=N3>=…Nn

正整数n的这种表示叫做正整数n的划分,正整数n的不同的划分的个数叫做n的划分数。记做pn)。

比如对于6

6;
5+1
4+2;4+11
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

【算法设计】:

在正整数n的所有划分中,将最大加数N1不大于m的划分的个数记做dividen,m),建立递关系式:

1):当最大加数不大于1的时候,只有一种划分形式,也就是1+1+1+1....

2):最大加数实际上不可能大于n,所以当m>n的时候,划分的个数也是1

3):当n=m的时候,正整数的划分是有N1=m和N1<=n-1的划分组成

4):当n>m>1的时候,正整数的最大加数N1不大于m的划分由N1=m的划分和N1<=m-1的划分组成。

思路如下:

if n=1,m=1:
	divide(n,m)=1;
if n<m:
	divide(n,m)=divide(n,n);
if m=n:
	divide(n,m)=1+divide(n,n-1);
if n>m>1:
	divide(n,n)=divide(n,m-1)+divide(n-m,m0;

【示例代码如下】:

/**
 * @author Rollen-Holt 正整数的划分
 * */
public class IntegerDivide{
	public static void main(String[] args){
		// 表示划分的个数
		int num = 0;
		//比如求6的划分的个数
		num = divide(6, 6);
		System.out.println(num);
	}

	public static int divide(int n, int m){
		if (n < 1 || m < 1) {
			return 0;
		} else if (n == 1 || m == 1) {
			return 1;
		} else if (n == m) {
			return 1 + divide(n, n - 1);
		} else if (n < m) {
			return divide(n, n);
		} else {
			return divide(n, m - 1) + divide(n - m, m);
		}
	}
}

【运行结果】:

11