问题描述:
将正整数n划分成n个正整数之和,
n=n1+n2+n3+......+nk(其中n1≥n2≥......≥nk≥1,k≥)
例如 整数5可以进行如下的划分
5=5
=1+4
=1+2+2
=1+1+3
=2+2+1
=2+3
=1+1+1+1+1
假设给的整数n可以关于m划分定义一个函数p(n,m)
那么会有以下几种情况出现
①当m=1时 即整数n关于1的划分 n=1+1+.....+1(n个1)
如前面举得例子5=1+1+1+1+1
即p(n,1)=1
②当n=1时 即给定的整数为1无论m取何值(当然这里的m不为负数)1=1
即p(1,m)=1
③当n<m时返回m=n 这就比如给定一个整数5求关于6的划分还是得按5来求一样的道理
返回 p(n,n)
④当m=n时可以进行拆分m划分一整块跟剩下的m-1进行分块而m分一整块的情况就一种所以可以这样写
p(n,m)=p(n,m-1)+1是等价的
就比如把5 分成了5划分跟5-1划分的两部分
⑤当n>m时又需要分情况n关于m的划分中包括m还是不包括m,
我们先来看包括m如何处理
包括m时相当于把n分成{m,(n1+n2+...nk)}又m+n1+n2+....+nk=n
所以 n1+n2+...nk=n-m 问题转化为整数n-m再次划分同时有可能再次出现m
比如5关于2的划分再划分时可能出现3关于2 的划分 即p(n-m,m)
不包括m时即划分的值都比m小即p(n,m-1)
结合起来就是 p(n,m)=p(n-m,m)+p(n,m-1)
分析完情况后就开始写代码
#include<stdio.h> int p(int n,int m){ if(n<1||m<1) return 0; if(n==1||m==1) return 1; if(n<m) return p(n,n); if(n==m) return p(n,m-1)+1; return p(n-m,m)+p(n,m-1); } int main() { int x,y,z; scanf("%d %d",&x,&y); z=p(x,y); printf("%d",z); }运行结果图如下