整数划分的递归实现算法c语言,整数划分算法原理与实现
整数划分问题是将一个正整数n拆成一组数连加并等于n的形式,且这组数中的最大加数不大于n。
如6的整数划分为
6
5 + 1
4 + 2, 4 + 1 + 1
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
共11种。下面介绍一种通过递归方法得到一个正整数的划分数。
递归函数的声明为 int split(int n, int m);其中n为要划分的正整数,m是划分中的最大加数(当m > n时,最大加数为n),
1 当n = 1或m = 1时,split的值为1,可根据上例看出,只有一个划分1 或 1 + 1 + 1 + 1 + 1 + 1
可用程序表示为if(n == 1 || m == 1) return 1;
2 下面看一看m 和 n的关系。它们有三种关系
(1) m > n
在整数划分中实际上最大加数不能大于n,因此在这种情况可以等价为split(n, n);
可用程序表示为if(m > n) return split(n, n);
(2) m = n
这种情况可用递归表示为split(n, m - 1) + 1,从以上例子中可以看出,就是最大加
数为6和小于6的划分之和
用程序表示为if(m == n) return (split(n, m - 1) + 1);
(3) m < n
这是最一般的情况,在划分的大多数时都是这种情况。
从上例可以看出,设m = 4,那split(6, 4)的值是最大加数小于4划分数和整数2的划分数的和。
因此,split(n, m)可表示为split(n, m - 1) + split(n - m, m)
根据以上描述,可得源程序如下:
int split(int n, int m)
{
if (n == 1 || m == 1)
{
return 1;
}
if (n < m)
{
return split(n, n);
}
if (n == m)
{
return 1 + split(n, m-1);
}
if (n > m)
{
return split(n-m, m) + split(n, m-1);
}
}
//
将正整数划分成连续的正整数之和如15可以划分成4种连续整数相加的形式:
15
7 8
4 5 6
1 2 3 4 5
首先考虑一般的形式,设n为被划分的正整数,x为划分后最小的整数,如果n有一种划分,那么结果就是x,如果有两种划分,就是x和 x + 1,如果有m种划分,就是 x 、x + 1 、x + 1 、x + 2 、... 、x + m - 1,将每一个结果相加得到一个公式(i * x + i * (i - 1) / 2) = n,i为当前划分后相加的正整数个数。
满足条件的划分就是使x为正整数的所有情况。
如上例,当i = 1时,即划分成一个正整数时,x = 15, 当i = 2时, x = 7。
当i = 3时,x = 4, 当i = 4时,4/9,不是正整数,因此,15不可能划分成4个正整数相加。
当i = 5时,x = 1。
这里还有一个问题,这个i的最大值是多少?不过有一点可以肯定,它一定比n小。我们可以做一个假设,假设n可以拆成最小值为1的划分,如上例中的1 2 3 4 5。这是n的最大数目的划分。如果不满足这个假设,那么 i 一定比这个划分中的正整数个数小。因此可以得到这样一个公式i * (i + 1) / 2 <= n,即当i满足这个公式时n才可能被划分。
综合上述,源程序如下:
int Split(int n)
{
int nCount = 0;
int i, j;
int x;
int t;
for (i = 1; ((i * (i+1)) / 2 <= n); ++i)
{
t = (i * (i - 1)) / 2;
if ((n-t)%i)
{
continue;
}
x = (n - t) / i;
for (j = x; j <= x+i-1; ++j)
{
cout<
}
cout<
++nCount;
}
return nCount;
}
posted on 2008-10-21 10:29 水 阅读(2954) 评论(5) 编辑 收藏 引用 所属分类: 算法与数据结构
整数划分的递归实现算法c语言,整数划分算法原理与实现相关推荐
- NYOJ90 整数划分(经典递归和dp)
整数划分 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+-+nk, 其中n1≥n2≥-≥nk≥1,k≥1. 正整数 ...
- java整数划分递归_整数划分(递归)
整数划分问题是算法中一个经典命题之一,有关问题的讲述在讲解到递归时基本都会提到: 所谓整数划分:指把一个正整数n写成如下形式: n=m1+m2+........mi;(mi为正整数,并且1<=m ...
- java合一算法_Prolog语言的编译原理:合一算法
Prolog语言的编译原理:合一算法 分类:软考 | 更新时间:2016-07-08| 来源:转载 Prolog是一种基于谓词演算的程序设计语言.Prolog是一种说明性语言,它的基本意思是程序员着重 ...
- 后序遍历的非递归算法python_二叉树后序遍历(递归与非递归)算法C语言实现...
二叉树后序遍历的实现思想是:从根节点出发,依次遍历各节点的左右子树,直到当前节点左右子树遍历完成后,才访问该节点元素. 图 1 二叉树 如图 1 中,对此二叉树进行后序遍历的操作过程为: 从根节点 1 ...
- 二叉树的非递归遍历算法C语言实现(详细注释版)
二叉树的非递归算法遍历分为:先序遍历,中序遍历,后序遍历. 此文章我会根据先.中.后的顺序为大家用C语言实现全部代码. 顾名思义先序遍历是先遍历根节点,随后是左孩子,右孩子 . 中序遍历与后序遍历可以 ...
- 二叉树的递归遍历算法c语言 数据结构,递归创建二叉树c语言实现+详细解释
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 void CreatBiTree(BiTree T) { char a; scanf("%c",&a); if(a=='@') ...
- 均匀不变lbp算法c语言代码,LBP原理介绍以及算法实现
有些读者可能会觉得奇怪,上次推送怎么就突然说起了双线性插值而不是继续介绍经典人脸识别的算法,其实是因为在学习圆形LBP算子的时候发现需要用到双线性插值于是顺带介绍了一下.(因为个人原因没经常看公众号的 ...
- 【递归】整数划分(C++)
一.什么是整数划分 所谓整数划分,是指把一个正整数n写成如下形式: n = m 1 + m 2 + ⋅ ⋅ ⋅ + m i n=m_1+m_2+···+m_i n=m1+m2+⋅⋅⋅+mi: 其 ...
- 整数划分c语言程序递归,递归整数划分
递归实现整数划分 目录 递归实现整数划分 1.原理 2.Python实现 3.C实现 1.原理 拿6为例,可划分为: 6 5+1 4+2 4+1+1 3+3 3+2+1 3+1+1+1 2+2+2 2 ...
最新文章
- MyBatis框架概述
- 功能点分析:商品类目表
- python 是什么类型的语言-python是一种什么类型的语言
- Android中通过ImageSwitcher实现相册滑动查看照片功能(附代码下载)
- 一键导出Origin图片MATLAB代码
- nginx 上传文件 405_今天教大家Nginx+tomcat负载均衡群集如何配置
- CentOS安装scp命令
- React 快速上手 - 目录索引
- 二叉树的遍历(先序/中序/后序,递归/迭代)与搜索
- 斗鱼+android下载地址,斗鱼下载2021安卓最新版_手机app官方版免费安装下载_豌豆荚...
- Linux事件驱动网络编程,Linux系统编程之事件驱动
- 你对锁的理解?如何手动模拟一个死锁?
- 万年历功能c语言,万年历(c语言多功能).doc
- GitHub:30%的新增代码出自AI工具Copilot之手
- mysql的英文文献_mysql数据库英文文献.doc
- 27-java String 之间比较的幺蛾子
- Windows10系统与Ubuntu系统之间的文件传输工具
- matlab 中simple什么意思,[求助]Matlab2016b里没有simple函数
- 7-DoG(差分高斯,Difference of Gaussina)
- 百分比,千分比,万分比,百分比或百分吕,千分率等
热门文章
- golang泛型介绍
- siesta在Linux运行,并行编译SIESTA
- 浏览器获取cookie失败,浏览器解决方案
- Smart PLC与Wincc通过Simatic NET建立OPC通讯(1)
- 中兴B863AV3.2-M_专用线刷刷机固件包及教程(线刷后不再需要卡刷)
- office文档管理服务器编辑,_卓正软件 - PageOffice官方网站 - 在线编辑Word、Excel的Office文档控件...
- 非线性有限元:基本理论与算法及基于Python、Fortran程序实现与案例分析实践技术
- 财务报表合并怎么快速完成
- 计算机毕设Python+Vue智慧工地管理系统(程序+LW+部署)
- android缓存清理无效,Android开发之清理系统缓存错误