POJ1664 放苹果 递归 C语言

题目:http://poj.org/problem?id=1664

自己想了半天,什么排列组合之类的,后来去搜题解,才知道是用递归…… 强大啊……

 个人感觉递归好神奇啊,反正就是一次一次调用然后结果就出来了,不用去想它具体是怎么实现的。

 

 

 这题的思想是找递归关系,我们不妨令f(m,n)表示m个苹果放到n个盘子里有多少种放法,下面对不同的情况给予讨论:

(1):当盘子数为1的时候,只有一种放法就是把所有苹果放到一个盘子里。

(2):当苹果数为1的时候,也只有一种放法,注意题目中说明,盘子之间并无顺序,所以不管这个苹果放在哪个盘子里,结果都算一个。

(3):m<n时,因为此时最多只能放到m个盘子中去(一个里放一个),实际上就相当于把m个苹果放到m个盘子里一样,也就是f(m,m);

(4):m==n,此时分两种情况讨论,一种是一个盘子里放一个,只是一种,第二种是,至少有一个盘子里不放苹果这就相当于是f(m,m-1);

(5):m>n时,也分两种情况讨论,一种是至少有一个盘子里不放苹果,这样子就相当于f(m,n-1),第二种是,先取出n个苹果一个盘子里放一个,再将剩下的m-n个苹果放到n个盘子里去,即f(m-n,n);

综上所述:

得到递归表达式:

f(m,n)=1 m=1n=1

f(m,n)=f(m,m) m<n;

f(m,n)=1+f(m,m-1) m=n;

f(m,n)=f(m-n,n)+f(m,n-1);

 


                         //  solution   NO. 1


 

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 

 

 

 另一种解释更加简单
                       // solution  NO. 2

 


 1  #include <stdio.h>
2 #include <stdlib.h>
3 int f (int m, int n) {
4 if (m == 0 || n == 1) //3.盘数等于果数 或 只有一个盘子 : 只有一种放法
5 return 1;
6 if (m < 0) //2.m-n < 0, 无剩余苹果 (盘数大于果数)
7 return 0;
8 return f(m - n, n) + f(m, n - 1); //1. 每个盘子放一个,剩余m-n个随意 + 空一个盘子 
9 }
10 int main () {
11 int t, m, n;
12 scanf ("%d", &t);
13 while (t--) {
14 scanf ("%d%d", &m, &n);
15 printf ("%d\n", f (m, n));
16 }
17 //system ("pause");
18 return 0;
19 }

 如果非要仔细想的话,我也想不明白……但是递归就是这样嘛……好强大好强大~

 

posted @ 2011-07-20 11:10  cloehui  阅读(779)  评论(0编辑  收藏  举报