放苹果问题
1、放苹果问题
问题描述:
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的放法?(用K表示)注意:5,1,1和1,5,1是同一种分法。
输入数据:
第一行是测试数据的数目t(0<=t<=20),以下每行均包含两个整数M和N,以空格分开。1<=M,N<=10。
输出要求:
对输入的每组数据M和N,用一行输出相应的K。
输入样例:
1
7 3
输出样例:8
2、代码实现
1 package com.wcy.october; 2 3 import java.util.Scanner; 4 5 /** 6 * 时间:2016年10月23日 7 * 问题描述:把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的放法?(用K表示)注意:5,1,1和1,5,1是同一种分法。 8 * 输入数据:第一行是测试数据的数目t(0<=t<=20),以下每行均包含两个整数M和N,以空格分开。1<=M,N<=10。 9 * 输出要求:对输入的每组数据M和N,用一行输出相应的K。 10 * 输入样例 11 * 1 12 * 7 3 13 * 输出样例 14 * 8 15 * 16 * 方法解析: 17 * 1、所有不同的摆放方法可以分为两类:至少有一个盘子空着和所有的盘子都不空。我们可以分别计算这两类摆放方法的数目,然后把它们加起来。对于至少空着一个 18 * 盘子的情况,则N个盘子摆放M个苹果的摆放数目与N-1个盘子摆放M个苹果的摆放方法数目相同。对于所有盘子都不空的情况,则N个盘子摆放M个苹果的摆放方法 19 * 数目等于N个盘子摆放M-N个苹果的摆放方法数目。我们可以据此来用递归的方法求解这个问题。 20 * 2、设f(m,n)为m个苹果,n个盘子的放法数目,则先对n作讨论,如果n>m,必定有n-m个盘子永远空着,去掉它们对摆放苹果放法数目不产生影响; 21 * 即if(n>m)f(m,n)=f{m,m}。当n<=m时,不同的方法可以分为两类:即有至少一个盘子空着或者所有盘子都有苹果,前一种情况相当于 22 * f(m,n)=f(m,n-1);后一种情况可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n)=f(m-n,n)。总的放苹果的放法数目等于两者 23 * 的和,即f(m,n)=f(m,n-1)+ f(m-n,n)。整个递归过程描述如下: 24 * int f(int m,int n){ 25 * if(n==1||m==0)return 1; 26 * if(n>m)return f(m,m); 27 * return f(m,n-1)+f(m-n,n)} 28 * 3、出口条件说明:当n=1是,所有苹果都必须放到一个盘子里,所有返回1,当没有苹果可放时,定义为1种放法。递归的两条路,第一条n会逐渐减少,终会达到 29 * 出口n==1;第二条m会逐渐减少,因为n>m时,我们会return f(m,m)所以终会到达出口m==0. 30 */ 31 public class Apple { 32 33 /** 34 * 求放置方法数目 35 * @param m 苹果数目 36 * @param n 盘子数目 37 * @return 放置方法数目 38 */ 39 public int getResult(int m,int n){ 40 if (n == 1 || m == 0) { 41 return 1; 42 }else if (m < n) { 43 return getResult(m, m); 44 }else { 45 return getResult(m, n-1) + getResult(m-n, n); 46 } 47 } 48 49 /** 50 * 用户页面测试 51 * @param args 52 */ 53 @SuppressWarnings("resource") 54 public static void main(String[] args) { 55 Apple apple = new Apple(); 56 Scanner reader = new Scanner(System.in); 57 int number = reader.nextInt(); 58 int[] result = new int[number]; 59 int m = 0; // 苹果数目 60 int n = 0; // 盘子数目 61 for (int i = 0; i < number; i++) { 62 m = reader.nextInt(); 63 n = reader.nextInt(); 64 result[i] = apple.getResult(m, n); 65 } 66 67 for (int i = 0; i < result.length; i++) { 68 System.out.println(result[i]); 69 } 70 } 71 }