递归算法
今天我们学习了用for循环去枚举每一种可能的答案。然而,有些题目用for循环是很难枚举出每一种情况的。所以明天我们要学习递归算法。这是明天要讲的题目,大家可以先看一下,想一下。
c语言课本“函数的递归调用”那一节可以作为学习的参考资料。
欢迎大家指正我程序中的错误,我会虚心接受;欢迎大家留言,我会认真回复的。
—————————————————分割线———————————————————————
1、放苹果
问题描述
把 M 个同样的苹果放在N 个同样的盘子里,允许有的盘子空着不放,问共有多少
种不同的分法?(用K 表示)注意:5,1,1 和1,5,1 是同一种分法。
输入数据
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含两个整数M 和N,以
空格分开。1<=M,N<=10。
输出要求
对输入的每组数据M 和N,用一行输出相应的K。
输入样例
1
73
输出样例
8
方法1:
为了不使程序出现5,1,1与1,1,5这类的重复,程序中用t记录了前一次分的苹果数,后一次分的苹果数永远小于等于前一次分的。
如果剩余苹果数为0时篮子还有剩余,则满足题意。
//放苹果
#include<stdio.h>
int M,N,K;
int m,k=0;//n:剩余盒子数 k:用的第k个盒子
int a[100]={0};
void DFS(int m,int t)//m:剩余苹果数,t:上次分的苹果数
{
if (m==0&&k<=N)
{
//for(int j=0;j<k;j++)
// printf("%d ",a[j]);
//printf("\n");
K++;
}
else
{
for(int i=M;i>0;i--)
if(i<=t&&i<=m)
{
m=m-i;
a[k++]=i;
DFS(m,i);
a[--k]=0;
m=m+i;
}
}
}
void main()
{
int t;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
K=0;
scanf("%d %d",&M,&N);
DFS(M,M);
printf("%d\n",K);
}
}
要将m个苹果放进n个篮子有三种情况:
1、若苹果数<篮子数,则f(m,n)=f(m,m),有n-m个篮子里必定没苹果,其余篮子里可能有,也可能没有。
2、若苹果数>篮子数,则又分两种情况:
1.所有的篮子里都有苹果f(m-n,n);
2.有个篮子没有苹果f(m,n-1);
<感觉这种方法像递推,,不过目前还不清楚是不是。。。>
3、篮子数为1或苹果数为0,则只有一种分法。
#include<stdio.h>
int apple(int m,int n)
{
if(m==0||n==1)
return 1;
if(m<n)
return (apple(m,m));
else
return (apple(m-n,n)+apple(m,n-1));
}
void main()
{
int m,n,t;
scanf("%d",&t);
for(int i=0;i<t;i++)
{
scanf("%d %d",&m,&n);
printf("%d\n",apple(m,n));
}
}
这篇博客介绍了如何使用递归算法解决将M个苹果放入N个盘子的不同分法问题。讨论了递归的基本概念,并给出了C语言相关的学习资源。文中提供了一个避免重复分法的程序思路,包括不同情况的递归处理,如苹果数小于篮子数、大于篮子数等。同时,博主鼓励读者提出错误和留言交流。
737

被折叠的 条评论
为什么被折叠?



