Java实现整数划分

整数的划分问题:将正整数n表示成一系列正整数之和,n=n1+n2+…+nk,其中n1>=n2>=…>=nk>=1,k>=1。
举个简单的例子:

6的划分:

	6;
	5+1;
	4+2,4+1+1;
	3+3,3+2+1,3+1+1;
	2+2+2,2+2+1+1+1,2+1+1+1+1;
	1+1+1+1+1+1;

通过写这个例子不难发现其中的递推关系
每个分号为一组,该组最大的加数为m,第三行m=4,在正整数n的所有不同的划分中,将最大加数n1不大于m的划分个数记做q(n,m)。
也就是说我们要求数字几的划分,也就是求q(n,n)

q(6,4)就是下面的这些:

	4+2,4+1+1;
	3+3,3+2+1,3+1+1;
	2+2+2,2+2+1+1,2+1+1+1+1;
	1+1+1+1+1+1;

现在来说一下递推关系:

  1. 当n=1,或者m=1时,q(n,m)=1
  2. 当n<m时,很明显这种是不正确的,我们设m是最大加数,m就只能小于等于n,所以这种情况就等同于q(n,n)
  3. 当n=m时,也就是q(n,n),这时如果返回q(n,n)那么就递推不下去了,这时可以举个例子理解一下
    q(6,6)就等于q(6,5)加上单独的数字6,在求划分数目也就是这样写:q(6,6)=q(6,5)+1
    推广得:q(n,m)=1+q(n,m-1)
  4. 这种是用到最多的情况,n>m时,还是举个例子理解
    q(6,4)有哪些:
		4+2,4+1+1;
		3+3,3+2+1,3+1+1;
		2+2+2,2+2+1+1,2+1+1+1+1;
		1+1+1+1+1+1;

可以将这些分为两部分,一部分是q(6,3),一部分是q(2,4)
q(6,3):

		3+3,3+2+1,3+1+1;
		2+2+2,2+2+1+1,2+1+1+1+1;
		1+1+1+1+1+1;
		q(2,4):
		4+2,4+1+1;

得到递推公式:q(n,m)=q(n,m-1)+q(n-m,m)
这样是不是就很清晰了,那为什么不把q(2,4)写成q(2,2)呢?也就是q(n,m)=q(n,m-1)+q(n-m,n-m)
再举个例子: q(6,2)=q(6,1)+q(5,2)
如果这块写成了q(6,2)=q(6,1)+q(5,5),很明显最大加数是2,后面式子确出现了q(5,5),这样是错误的,而且会多算很多划分的个数

分析清楚了,代码很简单,就是递归就行了

public class Main_1 {
    public static void main(String[] args) {
        System.out.println(split(6));
    }
    public static int split(int n) {
        return p(n,n);
    }
    public static int p(int n,int m) {
        if(n==1 || m==1) {
            return 1;
        } else if(n<m) {
            return p(n,n);
        } else if(n==m) {
            return p(n,n-1)+1;
        } else if(n>m) {
            return  p(n,m-1) + p(n-m,m);
        }
        return -1;
    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值