整数划分问题

   问题描述:

将正整数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);
}
运行结果图如下





猜你喜欢

转载自blog.csdn.net/weixin_37407422/article/details/80363161