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=1或n=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 }
如果非要仔细想的话,我也想不明白……但是递归就是这样嘛……好强大好强大~