POJ 1664 分苹果(递归)。

POJ 1664 分苹果。

(递归)
递归经常要用,但是作为新手用得不熟练。这道题其实不难,但是做的时候也看了一些别人的博客的分析。

题目:

/*
描述
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
输入
第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出
对输入的每组数据M和N,用一行输出相应的K。
样例输入
1
7 3
样例输出
8
*/

//自己写一下解题分析吧,再加深一下印象,更透彻理解。

解题分析:

原本第一眼看到题目的时候并不理解里面的t是什么意思,后来才知道是在问用户要测试多少组数据,所以在写程序的时候我自己加上了一点说明。
按苹果数与盘子数的大小来区分两种情况。
第一种情况:
苹果数比盘子数小,即(m小于n).
考虑到使用盘子数最多的情况是每个盘子放一个苹果,所有苹果放完之后就剩下(m-n)个盘子。但是这种情况下多于的盘子是没有意义的,因为题目已经说明了(5,1,1与1,5,1是同一种情况),所以当m小于n时,实际上应该考虑的情况等价于m个苹果,m个盘子
第二种情况:
苹果数大于等于盘子数,即 m>= n.
这时又细分两种情况,我区分说明记为a和b:
a是使没有盘子是空的情况:这时的分发为n个盘子每个放进一个苹果之后就没有盘子是空的,用去n个苹果,剩下(m-n)个苹果可以随意放到盘子中,变成(m-n)个苹果,n个盘子的情况,就从第一种情况开始重新考虑苹果的分配。递归的思想在这里体现。
b是使至少有一个盘子是空的情况:即考虑m个苹果,(n-1)个盘子的情况,满足了前提条件(至少有一个盘子空)之后,于是就从第一种情况开始重新考虑苹果的分配。递归的思想同样在这里体现。

分析完了就可以写递归的函数了;
用户输入完m,n之后,将m,n作为参数传入到递归函数中。
我将这个函数命名为distribute_apple,意思是分发苹果。虽然函数名长了点,但是意思明了。
函数应该是直接返回共有多少种情况的结果,所以定为int类型。
啰嗦完了。。开始写函数:

int distribute_apple (int m,int n){
//这里是递归函数的出口,当满足(m==0||n==1)时就可以结束递归。至于满足的条件为什么是这个,稍后解释;
if(m==0||n==1)
return 1;
if (m《n) //第一种情况; /PS:(不知道怎么,写博客的时候总是打小于号就后面的内容显示不了了。所以在这里用左书名号代替。)/
return distribute_apple(m,m); //等同于m个苹果,m个盘子的情况;
else //第二种情况;
return ( distribute_apple(m-n,n) + distribute_apple(m,n-1) ) ;
// 同为第二种情况,所以a和b情况的结果应该相加后返回。

// 在博客里直接写函数好累。。。空格猛敲。
至于为什么是(m==0||n==1),首先,当满足m==0时,就是苹果已经分完了,自然可以返回是一种情况。或者是 n==1时,盘子只剩下一个,也可以返回一种情况。

下面终于上源代码。。

#include<stdio.h>
int distribute_apple (int m,int n){
    if (m == 0 || n == 1) // 递归出口
        return 1;
    if (m < n)
        return distribute_apple(m,m);
    else // m>= n
        return distribute_apple(m-n,n)+distribute_apple(m,n-1);
}
int main()
{
    int t,m,n;
    int ct;
    int pos[20];

    printf("你打算测试多少组数据?(0<t<=20)\n");
    scanf("%d",&t);
    printf("先输入苹果数后输入盘子数。\n");
    for (ct = 0;ct<t;ct++){
        printf("1<=苹果数,且盘子数<=10.\n");
        scanf("%d %d",&m,&n);
        pos[ct] = distribute_apple(m,n);
        printf("共有%d种情况。\n",pos[ct]);
    }
    return 0;
}

第一次写博客。。因为题目太简单所有成就感很少。。但是还是继续努力。如果有发现错误,欢迎并恳请帮忙指出来。

你可能感兴趣的:(递归)