C 语言程序设计实践 6.5 分石头

★实验任务有一堆石头,共有 m 个,现在要你把他们分成小于等于 n 堆,一共有多少种不同的分法。 

 ★数据输入输入第一行包括一个正整数 T(T<=10),接下来共有 T 组数据,每组数据只有一行,每行有两个正整数,m 和 n(m,n<=20)。

 ★数据输出每组数据输出一个数 sum,表示 sum 种不同的分法。

输入示例 

1

7 3

输出示例

8

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define DEBUG
unsigned long GPC(int n,int max){
	if(n==1||max==1)
	return 1;
	if(n<max)
	return GPC(n,n);
	if(n==max)
	return 1+GPC(n,n-1);
	else
	return GPC(n-max,max)+GPC(n,max-1);
}
int main(){
	int a,n,m;
	unsigned long count;
	scanf("%d",&a);
	while(a--){
		scanf("%d%d",&n,&m);
		count=GPC(n,m);
		printf("%d\n",count);
	}
	return 0;
}
使用递归:

(1)当n=1时,不论m的值为多少(m>0),只有一种划分,即{1,1,1,1········1};

(2)当m=1时,不论n的值为多少(n>0),只有一种划分,即{1};

(3)当m=n时,根据划分中是否包含m,可以分为两种情况:

        (a)划分中包含m的情况,只有一个,即{m};

       (b)划分中不包含m的情况,这时划分中最大的数字也一定比m小,即m的所有(m-1)划分;

  因此,f(m,m) = 1 + f(m, m- 1)。 


4)当m<n时,由于划分中不可能出现负数,因此就相当于f(m,m);
5)当m>n时,根据划分中是否包含n,可以分为两种情况:
     (a)划分中包含n的情况,即{n,{x1,x2,x3,...,xi}},其中{x1,x2,x3,...,xi}的和为m-n,可能再次出现n,因此是(m-n)的n划分,因此这种划分个数为f(m-n,n);
     (b)划分中不包含n的情况,则划分中所有值都比n小,即m的(n-1)划分,个数为f(m, n - 1);
       因此,f(m,n) = f(m - n,n) + f(m, n - 1)。
n综合以上各种情况,可以看出,上面的结论具有递归定义的特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,而情况(5)为通用情况,属于递归的方法,其本质主要是通过减少n或m以达到回归条件,从而解决问题。
n其递归表达式如下所示:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值