Java题解 | HJ61 #放苹果#
放苹果
https://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf
描述
把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。
数据范围: 0≤m≤10
, 1≤n≤10
。
输入描述:
输入两个int整数
输出描述:
输出结果,int型
示例1
输入: 7 3 输出: 8
解法:递归
设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论,
- 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即
if(n>m) f(m,n) = f(m,m)
- 当n<=m:不同的放法可以分成两类:
- 1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1);
- 2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n).
- 而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n)
递归出口条件说明:
- 当n=1时,所有苹果都必须放在一个盘子里,所以返回1;
- 当没有苹果可放时,定义为1种放法;
递归的两条路,
- 第一条n会逐渐减少,终会到达出口n==1;
- 第二条m会逐渐减少,因为n>m时,我们会return f(m,m) 所以终会到达出口m==0
/** * Welcome to https://waylau.com */ package com.waylau.nowcoder.exam.oj.huawei; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; /** * HJ61 放苹果. * 描述:把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法? * 注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。 * 数据范围: `0≤m≤10` , `1≤n≤10` 。 * 输入描述: * 输入两个int整数 * 输出描述: * 输出结果,int型 * 示例1 * 输入: * 7 3 * 输出: * 8 * * @since 1.0.0 2022年8月27日 * @author <a href="https://waylau.com">Way Lau</a> */ public class HJ061PutApple { public static void main(String[] args) throws IOException { // 输入 BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String[] in = br.readLine().split(" "); int appleNamber = Integer.valueOf(in[0]); int plateNamber = Integer.valueOf(in[1]); // 输出 System.out .println(getWays(appleNamber, plateNamber)); // 关闭 br.close(); } private static int getWays(int appleNamber, int plateNamber) { // 只有1个盘子或者只有1个苹果,那只有1种分发 if (appleNamber == 1 || plateNamber == 1) { return 1; } // 没有也是1种分发 if (appleNamber == 0) { return 1; } // 没有盘子就分不成了 if (plateNamber == 0) { return 0; } // 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。 // 即`if(n>m) f(m,n) = f(m,m)` if (plateNamber > appleNamber) { return getWays(appleNamber, appleNamber); } // 当n<=m:不同的放法可以分成两类: // 1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1); // 2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n). // 而总的放苹果的放法数目等于两者的和,即 f(m,n) =f(m,n-1)+f(m-n,n) return getWays(appleNamber, plateNamber - 1) + getWays(appleNamber - plateNamber, plateNamber); } }
参考引用
- 本系列归档至https://github.com/waylau/nowcoder-exam-oj
- 《Java 数据结构及算法实战》:https://github.com/waylau/java-data-structures-and-algorithms-in-action
- 《数据结构和算法基础(Java 语言实现)》(柳伟卫著,北京大学出版社出版):https://item.jd.com/13014179.html