算法-中秋节分月饼-Java

一、中秋节分月饼 | 题目描述:

        中秋节公司分月饼,m个员工,买了n个月饼,m<=n,每个员工至少分1个月饼,但可以分多个,单人份到最多月饼的个数为Max1,单人分到第二多月饼的个数是Max2,Max1-Max2<=3。单人分到第n-1多月饼的个数是Max(n-1),单人分到第n多月饼的个数是Max(n),Max(n-1)-Max(n)<=3。问有多少种分月饼的方法?
输入描述:
每一行输入m n,表示m个员工,n个月饼,m<=n
输出描述:
输出有多少种月饼分法
示例:
输入
2 4
输出
2

二、解题思路总结:

这道题百思不得其解,最终通过学习思考,认定这是一道递归问题,最终通过研究借鉴逻辑,得出如下Java代码。

思路总结如下:
1. m个人有n个月饼,先将m个人每个人分一个,剩余总月饼数为n-m=p;
2. 假设第一个人最少分k个,第二个人范围就是[k, k+3],Max(n-1)-Max(n)<=3
3. 当m为3个人时情况如下:
4. 我们假设第一个人总是分到最少的,第二个人分到第二少的,依次类推;
第一个人最少分0个(n-m后的p,就是给每位各分了一个后剩余的月饼数),剩下两个人有n-3(p)个月饼可分,此时,如果第二个人分k个,第三个人就是n-3-k(p-k)个,满足k<=p-k <= k+3(第三个人比第二个人的只多0-3个);
5. 依次循环类推,如果第一个人分1个,剩下两个人分n-3-1个,循环逻辑一致;
6.同理,如果是四个人时,分为第一个人和后三个人,后三个人又分为第一个人和后两个人,第一个人总是分最少的,第二个比他多0-3个,依次类推,我们发现这是一个递归调用过程。代码需要有一个递归函数distribute,给他下一个数量,并让他完成递归判断。当然对于两个人的情况,我们单独判断即可。

三、代码如下:

import java.util.Scanner;
public class Main
{ public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int n = sc.nextInt();
        int p =n-m;
        int count=0;

        if (m > n) {System.out.println(0);return ;}

        int i=0;
        for(i=0;i<p;i++)
            {
               count=count+distribute(m-1,p-i,i);
            }
            System.out.println(count);
        }

    public static int  distribute(int m ,int p, int k) {
        if (p <= 0) return 0;
        if (m <= 0) return 0;

        if (m == 1) {
            if (p >= k && p <= k + 3) {
                return 1;
            }
             return 0;
        }
        int ncount=0;
        for (int i = k; i <= k+3; i++) {
            ncount=ncount+distribute(m-1,p-i,i);
             }
          return ncount;
          }
    }

  • 6
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

国林哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值