Java题解 | HJ61 #放苹果#

放苹果

https://www.nowcoder.com/practice/bfd8234bb5e84be0b493656e390bdebf

描述

把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。

数据范围: 0≤m≤101≤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);
    }
}

参考引用

#华为机考#
全部评论

相关推荐

像好涩一样好学:这公司我也拿过 基本明确周六加班 工资还凑活 另外下次镜头往上点儿
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务