题解 | #放苹果#
个人思路,仅供参考,递归解法:
一、确定终止条件,用递归肯定到最后得有结束条件吧。
由于是两个变量,我们看看这两个变量最简单的时候是什么结果?
(1)m=0或m=1:没有苹果或只有一个苹果,那方式只有一种
(2)n=1:只有一个盘子,那苹果只能放在这一个盘子上,方式也只会有一种
二、确定递归体(本题难点),也就是怎么把复杂的m个苹果,n个盘,转化成更简单的情况。
首先是需要往简单的靠,那就考虑m 和 n ,跟 m-1 和 n-1到底有什么关系?假设F(m,n)就是求m个苹果n个盘情况下的方式总数,那现在就是考虑 F(m,n)和F(m-1,n)、F(m,n-1)有什么关系?
1、【m在变】 一开始我是在想,假设不考虑盘子变化,m个苹果去分配,跟m-1个苹果去分配有什么关联?m中多出来的一个苹果如果在m-1中分配?
这个情况我没想明白,看下一个。
2、【n在变】 假设不考虑苹果变化,n个盘子和n-1个盘子有什么关联呢?这里有两个考虑方向,简单-->复杂,复杂-->简单。
(1)n-1个盘子加了一个盘子,变成n个盘子,分配方式如何变化?
(2)n个盘子拿走了一个盘子,变成n-1个盘子,分配方式如何变化?
上面两种思考的方向,我觉得对推导递归体可能会有不同的效果吧。第一个一般是写动态规划代码的考虑,第二个就比较容易联想递归的方式。
拿走了一个盘子,相当于这个盘子不存在,也就是说,n个盘子,保证1个盘子是空的,剩下盘子去分配m个苹果。
【关键点】来了,F(m,n)可以分成两种情况,存在一个空盘子,不存在空盘子。
1)m个盘子中存在一个空盘子,那么分配方式有多少种?答案是F(m,n-1)
2)m个盘子中不存在空盘子,那么分配方式有多少种?答案是F(m-n,n) ,
因为要考虑不存在空盘子,那每个盘子中不就必须先分配1个吗?也就是能给我们分配的只要m-n个了。
最终结果出来了,F(m,n) = F(m,n-1) + F (m-n,n)
补充:还有一个情况,盘子太多了,一定有空盘,那分配方式我们可以直接省略空盘,直接考虑盘子跟苹果数一样的情况下的分配方式。
三、编码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] s = sc.nextLine().split(" ");
int m = Integer.parseInt(s[0]);
int n = Integer.parseInt(s[1]);
System.out.println(f(m,n));
}
public static int f(int m,int n){
//确定终止条件
if ( m == 0 || m == 1 || n == 1){
return 1;
}
//确定递归体
if (n > m){
return f(m,m);
}
return f(m-n,n) + f(m,n-1);
}
}
阿里云成长空间 745人发布