算法设计----整数划分递归相关问题

一.原问题

整数划分,是指把一个正整数n写成如下形式:

假设整数n,能被划分为i段n=a1+a2+...ai,其中ak为n中划分的最大整数(1<=ak<=n,1<=k<=i),则{a1,a2...ai}是n的ak的一个划分

当n=6时我们可以获得以下这几种划分

一共有11种

分析:讨论整数n和划分的最大整数m的关系,可以分为以下几种情况:

①当整数n==1,只有一种划分,即{1}

②当划分的最大整数m==1时,只有一种划分,即{1,1......1}

③当n<m时,整数n可以划分的最大的数为n,即f(n,n)种划分

④当n==m时,根据需不需要划分最大整数m,可以分为两种情况:

a:需要划分最大整数为m,只有一种划分,即{m}

b:不需要划分最大整数为m,即可能划分的最大整数为m-1,即有f(n,m-1)种划分

⑤当n>m时,根据需不需要划分最大整数m,可以分为两种情况:

a:需要划分最大整数为m,所以继续在n-m中划分,划分的最大整数还可能为m,所以有f(n-m,m)种划分

b:不需要划分最大整数为m,所以划分的最大整数可能为m-1,即有f(n,m-1)种划分

综上所述的转移状态方程:

1                  当 n==1或 m==1时

f(n,m)=     f(n,n)           当n<m时

1+f(n,m-1)   当n==m时

f(n-m,m)+f(n,m-1)   当n>m时

python源代码:

​
#整数划分问题
#假设整数n,能被划分为i段n=a1+a2+...ai,其中ak为n中划分的最大整数(ak<=n,k<=i),其中{a1,a2...ai}是n的ak的一次划分
#现在求整数n能够划分成多少种
def huafen(n,m):  #n为整数,m为划分的最大整数,m<=nif(n==1 or m==1):return 1elif n==m:return 1+huafen(n,m-1) elif(n<m):return huafen(n,n)else:return huafen(n,m-1)+huafen(n-m,m)a=[]
t=0
def digui(sum,k,m,l):global aglobal tif(sum>l):returnelif(sum==l):t+=1print("第",t,"种:")for x in range(len(a)-1):print(str(a[x])+"+",end="")print(a[-1])else:c=range(m)for y in reversed(c):y+=1sum+=y   a.append(y)    #加入到a列表中digui(sum,k+1,y,l)  #递归调用a.pop()   #出列表,恢复现场,回溯sum-=y  #恢复现场,回溯def main():print("请输入一个整数:")v=int(input())p=huafen(v,v)print("该整数的划分一共有"+str(p)+"种")print("所有的划分如下:")digui(0,0,v,v)main()​

运行结果如下:

二.变形1

如果限制每一个划分的整数不能一样,即划分的每一个整数不同  ,则又有多少种划分呢?

其实我们只需在原问题进行修改即可:

①当m==1时,我们需要设置{1,1,1,....1}为0种

②当n>m时,我们需要修改的是当需要选取最大整数m时  ,我们将最大值m-1,即f(n-m,m-1) 种

其余的不需要修改

pythoon源码:

#整数划分变形问题
def huafen(n,m):  #n为整数,m为划分的最大整数,m<=nif(n==1):return 1elif(m==1):   #当m==1时,设置1,1,1.....1}为0种return 0elif n==m:return 1+huafen(n,m-1)elif(n<m):return huafen(n,n)else:return huafen(n,m-1)+huafen(n-m,m-1)   #使下次划分的整数小于上次的划分的最大整数a=[]
t=0
def digui(sum,k,m,l):global aglobal tif(sum>l):returnelif(sum==l):t+=1print("第",t,"种:")for x in range(len(a)-1):print(str(a[x])+"+",end="")print(a[-1])else:c=range(m)for y in reversed(c):y+=1sum+=ya.append(y)digui(sum,k+1,y-1,l)   #这里需要将下一次的最大划分整数修改为上一次划分最大整数-1,不能与上一次相同a.pop()sum-=ydef main():print("请输入一个整数:")v=int(input())p=huafen(v,v)print("该整数的划分一共有"+str(p)+"种")print("所有的划分如下:")digui(0,0,v,v)
main()

运行结果如下:

三.变形2

如果限制每次划分的整数的个数 ,则又有多少种划分呢?(类似与盘子分苹果问题)

(其中n为整数,每次划分只能划分为m个数)

分析:①当m==1时,只有一种划分,即{n}

②当n<m时,由于划分的整数不可能为负数和小数,则划分不尽,所以为0

③当n==m时,也是只有一种划分。即{1,1,1,1...1}

④当n>m时,根据划分的整数中是否包含1,可以分为两种情况:

a:划分的整数中至少有一个1,则在n-1中继续划分为m-1份,即f(n-1,m-1)种划分

b:划分的整数中没有1,所以m个部分划分的整数必须都大于1,所以先给m个部分设为1,接着将剩余的n-m整数对m个部分分别加数,即要保证m个部分均大于1,即n-m>=m,则总共有f(n-m,m)种;如果n-m<m,则f(n-m,m)为0,所以条件②不能省略

综上所述方程:

1    当m==1 或者 n==m 时

f( n,m) =    0   当m>n时

f(n-1,m-1)+f(n-m,m)    当n>m时

python源代码:

#整数划分变形问题
def huafen(n,m):  #n为整数,m为每次划分的整数个数if(m==1 or n==m):return 1elif(m>n):   #当m>n时return 0else:return huafen(n-1,m-1)+huafen(n-m,m)   #选取至少有一个1和不选取1的种数
a=[]
t=0
def digui(sum,k,m,l,q):global aglobal tif(sum>l):returnelif(k==q and sum==l):t+=1print("第",t,"种:")for x in range(len(a)-1):print(str(a[x])+"+",end="")print(a[-1])else:c=range(m)for y in reversed(c):y+=1sum+=ya.append(y)digui(sum,k+1,y,l,q)   a.pop()sum-=ydef main():v,g=map(int,input("请输入两个以空格隔开的数:").split())  #整数v,和每次划分的整数个数gp=huafen(v,g)  print("该整数的划分一共有"+str(p)+"种")print("所有的划分如下:")digui(0,0,v,v,g)
main()

 运行结果如下:

三.变形3

如果n划分成若干个奇正整数之和 ,则这样有多少种划分?

(f(n,m)代表有多少种划分,其中n为整数,m为不大于n的最大整数的划分)

分析:①当m==1时,只有一种划分,即{1,1,...1}

②当m为奇数时:根据m和n的关系可以分成三种情况

a.当n<m时,则有f(n,n)种划分

b.当n==m时,根据是否选取最大整数m,可以分成两种情况

*选取最大奇整数m,则只有一种划分,即{m}

*不选取最大奇整数m,则共有f(n,m-2)种划分

c.当n>m时,根据是否选取最大整数m,可以分成两种情况

*选取最大奇整数m,则共有f(n-m,m)种划分

*不选取最大奇整数m,则共有f(n,m-2)种划分

③当m为偶数时:根据m和n的关系可以分成三种情况:

a.当n<m时,可以分成两类:(m为偶数,则m-1为最大奇数)

*当n<m-1时,则共有f(n,n)种划分

*当n==m-1时,则共有f(n,m-1)种划分

b.当n==m时,则共有f(n,m-1)种划分

c.当n>m时,根据是否选取最大奇整数m-1,可以分成两种情况

*选取最大奇整数m-1,则共有f(n-m+1,m-1)种划分

*不选取最大奇整数m-1,则共有f(n,m-3)种划分

python源代码:

def huafen(n,m):  #n为整数,huafen(n,m)代表:m为划分的最大整数共有多少种,m<=nif(m==1):  #若m==1return 1elif (m%2):  #若m为奇数if(n<m):  #n<mreturn huafen(n,n)elif(n==m):   #是否选取最大奇整数mreturn 1+huafen(n,m-2)else:    #是否选取最大奇整数mreturn huafen(n-m,m)+huafen(n,m-2)else:  #若m为偶数if(n<m):if(n<m-1):return huafen(n,n)else:return huafen(n,m-1)elif(n==m):return huafen(n,m-1)else:   #是否选取最大奇整数m-1return huafen(n-m+1,m-1)+huafen(n,m-3)
a=[]
t=0
def digui(sum,k,m,l):global aglobal tif(sum>l):returnelif(sum==l):flg=1for x in a:   #在原问题答案的基础下,挑选出整数全部都是偶数的列表if(x%2==0):flg=-1breakif(flg==1):t+=1print("第",t,"种:")for x in range(len(a)-1):print(str(a[x])+"+",end="")print(a[-1])else:c=range(m)for y in reversed(c):y+=1sum+=ya.append(y)digui(sum,k+1,y,l)a.pop()sum-=ydef main():print("请输入一个整数:")v=int(input())p=huafen(v,v)print("该整数的划分一共有"+str(p)+"种")print("所有的划分如下:")digui(0,0,v,v)
main()

运行结果如下:

整数划分递归相关问题相关推荐

  1. java整数划分递归_整数划分问题(递归法)

    整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及.所谓整数划分,是指把一个正整数n写成如下形式: n=m1+m2+...+mi; (其中mi为正整数,并且1 < ...

  2. java整数划分递归_整数划分(递归)

    整数划分问题是算法中一个经典命题之一,有关问题的讲述在讲解到递归时基本都会提到: 所谓整数划分:指把一个正整数n写成如下形式: n=m1+m2+........mi;(mi为正整数,并且1<=m ...

  3. NYOJ90 整数划分(经典递归和dp)

    整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+-+nk,  其中n1≥n2≥-≥nk≥1,k≥1.  正整数 ...

  4. 实验一 分治与递归—整数划分 java实现

    基本题一:基本递归算法 一.实验目的与要求 1.  熟悉Java语言的集成开发环境: 2.通过本实验加深对递归过程的理解 二.实验内容: 掌握递归算法的概念和基本思想,分析并掌握"整数划分& ...

  5. Bailian4117 简单的整数划分问题【整数划分+记忆化递归】

    4117:简单的整数划分问题 总时间限制: 100ms 内存限制: 65536kB 描述 将正整数n 表示成一系列正整数之和,n=n1+n2+-+nk, 其中n1>=n2>=->=n ...

  6. 整数划分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 ...

  7. 整数划分的递归实现算法c语言,整数划分算法原理与实现

    整数划分问题是将一个正整数n拆成一组数连加并等于n的形式,且这组数中的最大加数不大于n. 如6的整数划分为 6 5 + 1 4 + 2, 4 + 1 + 1 3 + 3, 3 + 2 + 1, 3 + ...

  8. 【递归】整数划分(C++)

    一.什么是整数划分 所谓整数划分,是指把一个正整数n写成如下形式: n = m 1 + m 2 + ⋅ ⋅ ⋅ + m i n=m_1+m_2+···+m_i n=m1​+m2​+⋅⋅⋅+mi​: 其 ...

  9. C语言接收一个整数划分成5的倍数,整数划分为连续整数;整数划分

    参考博客:http://www.cnblogs.com/nokiaguy/archive/2008/05/11/1192308.html 1.整数划分为连续整数: 如将15划分为连续整数之和: 15 ...

最新文章

  1. 薅百度GPU羊毛!PaddlePaddle大升级,比Google更懂中文,打响AI开发者争夺战
  2. C++——新类型与原始字面量(原始字符串)
  3. 很有趣的问题,Public继承和默认的集成
  4. php 5.6 新特性,PHP5.6新特性介绍
  5. Linux终端下 dstat 监控工具
  6. 7开启uasp协议_Dubbo-go 源码笔记(一)Server 端开启服务过程
  7. [学习笔记]python
  8. DataTable不能通过已删除的行访问该行的信息解决方法
  9. 前端学习(3026):vue+element今日头条管理-让导航栏和路由对应起来
  10. php框架laravel百科,PHP 的Laravel 框架
  11. 2019计算机组成原理及答案,2019计算机组成原理复习题(一)
  12. Mysql drop table 原理_mysql事务的实现原理
  13. Apizza-流程测试模式
  14. 『常识』罗胖的《罗辑思维》中推荐的书 — 未校正
  15. windows清理_一个Windows系统下好用的内存清理工具
  16. php联想输入,联想笔记本电脑键盘功能基础知识
  17. echart地图隐藏南海诸岛
  18. 使用grub4dos制作多系统启动U盘(win7、ubuntu12.04)
  19. php搞笑证件,摆摊证制作软件app 摆摊证搞笑图片怎么做
  20. 电子设计解决方案透视

热门文章

  1. boost::mp11::mp_set_contains相关用法的测试程序
  2. boost::gil::compute_hessian_responses用法的测试程序
  3. GDCM:Traverse Modules的测试程序
  4. DCMTK:简单存储服务类提供者
  5. VTK:Rendering之DiffuseSpheres
  6. VTK:绘图之HistogramBarChart
  7. C语言在BST中找到最接近目标的值的算法(附完整源码)
  8. OpenGL linesmooth线平滑的实例
  9. C语言十六进制数转八进制(十进制作为中介)(附完整源码)
  10. 经典C语言程序100例之九九