1. 题目
读题
考查点
2. 解法
思路
HJ61 放苹果是一个经典的动态规划或递归问题,要求用JAVA语言实现。它的基本思路是:
- 设f(m,n)为m个苹果,n个盘子的放苹果方式数目,那么有以下两种情况:
- 如果n>m,即盘子多于苹果,那么有n-m个盘子永远空着,不影响放法数目,所以f(m,n) = f(m,m)。
- 如果n<=m,即盘子少于或等于苹果,那么有以下两种子情况:
- 有一个或多个盘子为空,那么问题转化为将m个苹果放在n-1个盘子上,即f(m,n) = f(m,n-1)。
- 没有盘子为空,那么每个盘子上至少有一个苹果,那么问题转化为将m-n个苹果放在n个盘子上,即f(m,n) = f(m-n,n)。
- 综合以上情况,可以得到递推公式:f(m,n) = f(m,n-1) + f(m-n,n)。
- 递归的终止条件是:当m=0或n=1时,只有一种放法,返回1。
代码逻辑
具体实现
import java.util.Scanner;
/**
* HJ61 放苹果 - 简单
*/
public class HJ061 {
public static void main (String [] args) {
Scanner sc = new Scanner (System.in);
while (sc.hasNextInt ()) {
int m = sc.nextInt (); // 苹果数
int n = sc.nextInt (); // 盘子数
System.out.println (count (m, n)); // 输出放法数目
}
sc.close ();
}
/**
* m 苹果数
* n 盘子数
*/
private static int count (int m, int n) {
// 一个盘 或者 没有苹果 代表一种方案
if (n == 1 || m == 0) {
return 1;
} else if (n > m) { // 盘子过多情况,多余的盘子不起任何作用,最大的有效盘子是 m 个
return count (m, m);
} else { // 情况一: 只用 n - 1个盘子
// 情况二: 每个盘子里先放一个苹果,等价于 m - n个苹果放到 n 个盘子
return count (m, n - 1) + count (m - n, n);
}
}
}