整数划分/切割(Integer Partion),并输出结果, java, python

58 篇文章 35 订阅

整数划分是一个比较典型的递归问题:将一个整数 n n n 划分为值不超过 m m m 的一系列数的组合。
例如,若 n = 5 n=5 n=5, m = 4 m=4 m=4, 则划分可以为:{4,1}, {3,1,1}, {3,2}, {2,1,1,1}, {2, 2, 1},{1,1,1,1,1}。共有 6 个组合。

记组合个数为 f ( n , m ) f(n,m) f(n,m),则递归公式为:
f ( n , m ) = { f ( n , m − 1 ) + f ( n − m , m ) n > m > 1 1 + f ( n , m − 1 ) n = m > 1 f ( n , n ) m > n > 1 1 n = 1  or  m = 1 f(n,m)=\begin{cases} f(n,m-1)+f(n-m,m)\quad &n>m>1\\ 1+f(n,m-1)\quad & n=m>1\\ f(n,n) & m>n>1\\ 1 &n=1\text{ or } m=1 \end{cases} f(n,m)=f(n,m1)+f(nm,m)1+f(n,m1)f(n,n)1n>m>1n=m>1m>n>1n=1 or m=1

第一个等式分包不包含 m m m 两种情况。
若只要输出划分的总数,网上参考资料比较多,也比价容易理解。
若还要求把具体的划分结果输出,网上资料比较少,我自己从国外网站搜了下,找到了一个答案,同样利用到了递推思想,主要是:

**函数中多了一个字符串参数,并且当 $n$ 值下降到 0 时,换行**。

java 代码:

/** 
* @author chen zhen 
* @version 创建时间:2018年4月25日 下午4:51:23 
* @value 类说明: 整数划分,并输出结果
*/
public class IntegerPartion {
	
	// 查询划分次数
	static int countPartion(int n, int m) {
		if (n ==1 || m == 1)
			return 1;
		else if (m > n)
			return countPartion(n, n);
		else if (m ==n )
			return 1 + countPartion(n, n-1);
		else if (m < n)
			return countPartion(n-m, m) + countPartion(n, m-1);
		return 0;
	}
	
	// 输出具体划分
	static void countOutput(int n, int m, String str) {
		if (n == 0) // 递归跳出条件1
			System.out.println(str);
		else {
			if (m > 1) // 递归跳出条件2
				countOutput(n, m-1, str);
			if (m <= n) // 因为递归时可能出现 m>n 的情况
				countOutput(n-m, m, m + " " + str);
		}
	}

	public static void main(String[] args) {
		int m = 5;
		int n = 6;
		System.out.println(countPartion(m, n));
		countOutput(m, n, "");
	}
}

Python 代码:

# 输出整数划分个数
def f1(n, m):
    if n==0 or m ==0:
        return 0
    if n==1 or m ==1 :
        return 1
    if m == n:        
        return 1 + f1(n, n-1)
    elif m > n:
        return f1(n, n)
    elif m < n:
        return f1(n-m, m) + f1(n, m-1)

# 输出具体的整数划分
def f2(n, m, string):
    if n == 0:
        print(string)
    else:
        if m>1:
            f2(n, m-1, string)
        if m <= n:
            f2(n-m, m, str(m)+ ' '+string) 

n = 5; m = 4
print(f1(n, m))
f2(n, m, '')

输出结果:
6
1 1 1 1 1
1 1 1 2
1 2 2
1 1 3
2 3
1 4

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

心态与习惯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值