递归与分治之整数划分


《计算机算法设计与分析》第三版递归与分治章节 有一个整数划分问题。

将正整数n表示成一系列正整数值和: n = n1+n2+....+nk。

正整数n的这种表示称为正整数的n的划分。正整数n的不同的划分个数称为正整数的n的划分数,将最大加数记作m,记作p(n,m)。

例如:

6;                       a

5+1;                     b                  

4+2, 4+1+1;      c

3+3, 3+2+1,3+1+1+1;         d

2+2+2,2+2+1+1,2+1+1+1+1;       e

1+1+1+1+1+1;         f

可能我们已经注意到划分的规律了,这么多中表示方式中都有一个最大值,我们记作m,我们可以不断分治缩小最大值的,来找到如下递归规律。

n表示正整数,而m表示n由不同系列正整数组成当中的最大值。而m的最大值为n,所以我们的思想是先将m设为n,再次递减m(直至m=1为止【最大值为1的话,就一种方案,全为 1】),不断求的划分的方案。

1 . n==1  或 m == 1  任何正整数只有一种划分方式 n = 1+1+...+1  其中有m个1

2 . m >= n  最大值等于n,说明其他比较小的值都为0,所以划分方式只有一种 n = m.

所以p(n.m)= 1+p(n,m-1);而m-1肯定是小于n的。

3 . m( 将2中的m-1当做一个整体 ) < n,又有以下的规律 p(n,m) = p(n,m-1)+p(n-m,m)

详细说明p(n,m-1)和p(n-m,m)。 p(n,m-1)我们说过需要不断的递减m,直至m到1为止。这就是我们前面说的方案。比如看到我们的6从6,5,4,3,2,1递减,a-f。

p(n-m,m),当 m<n的时候,我们就要执行这句。从b中,6=5+1,我们还需要分配1这个方案。4+1+1,。3+2+1,3+1+1+1.。2+2+1+1,2+1+1+1+1这些方案都由这句来分配。


以上是我个人理解,我觉得说的还挺详细的。看着书上这么混乱的讲解,我觉得讲解还算清楚。以下是源码:

#include <iostream>
using namespace std;

int divide(int ,int);

int main()
{
	int n;
	while( cin>>n )
	{
		cout<<divide(n,n)<<endl;
	}
	return 1;
}

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


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值