分苹果的算法

Posted 我的成功之路

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了分苹果的算法相关的知识,希望对你有一定的参考价值。

题目:

把M个一样的苹果放在N个同样的盘子里,允许盘子空着不放,问共有多少种不同的分法?

N<=10。

测试样例:

7个苹果、3个盘子,有8种放发。

说明:

5,1,1和1,5,1算同样的分法。即盘子是无差别的盘子,苹果也是一样的苹果。

 

参考答案是使用递归算法,有点难度。

下面是一种简单粗暴的近似算法:蒙特卡罗算法。在苹果、盘子不多的情况下效果良好。

    public static int force(int apples, int plates) {  //蒙特卡罗算法

        HashSet<String> set = new HashSet<>();  //set用于统计分配方案
        int[] array = new int[plates];  //数组模拟盘子
        Random rnd = new Random();  //随机数
        for (int i=0; i<2000_0000; i++) { 
            Arrays.fill(array,0);
            int balance = apples;  //剩余苹果数
            for (int j=0; j<plates-1; j++) {  //随机给盘子分苹果
                int x = rnd.nextInt(balance+1);
                array[j] = x;
                balance =balance - x;
                if (balance == 0) {  //苹果已经分完,提前结束
                    break;
                }
            }
            array[plates-1]=balance;  //剩余苹果放到最后一个盘子里
            Arrays.sort(array);
            set.add(Arrays.toString(array));
        }
        return set.size();
    }

 

参考答案:递归算法。

    public static int f(int apples, int plates) {  //递归算法

        if (apples <= 0) {
            return 1;  //没有苹果(盘子有剩)也算一种方案
        }
        
        if (plates <=0) {
            return 0;  //没有盘子(苹果有剩)不算方案
        }
        
        if (plates > apples) {
            return f(apples, apples);  //盘子过多,直接去掉多余盘子
        }
        
        int sum0 = f(apples, plates-1);  //要么有一个盘子退出分配
        int sum1 = f(apples-plates, plates);  //要么每盘先预留一个苹果
        return sum0 + sum1;
    }

 

蓝桥杯 算法训练 ALGO-121 猴子分苹果

  算法训练 猴子分苹果  
时间限制:1.0s   内存限制:256.0MB
问题描述
  秋天到了,n只猴子采摘了一大堆苹果放到山洞里,约定第二天平分。这些猴子很崇拜猴王孙悟空,所以都想给他留一些苹果。第一只猴子悄悄来到山洞,把苹果平均分成n份,把剩下的m个苹果吃了,然后藏起来一份,最后把剩下的苹果重新合在一起。这些猴子依次悄悄来到山洞,都做同样的操作,恰好每次都剩下了m个苹果。第二天,这些猴子来到山洞,把剩下的苹果分成n分,巧了,还是剩下了m个。问,原来这些猴子至少采了多少个苹果。
输入格式
  两个整数,n m
输出格式
  一个整数,表示原来苹果的数目
样例输入
5 1
样例输出
15621
数据规模和约定
  0<m<n<9
 
题目解析:
  利用递推思想从后往前想,苹果和猴子的数量相等时苹果最少。苹果被分了 n+1 次,吃了 n 次,最后分完后还剩 m 个。
  因此,得到公式: Total = n^(n+1) - n*m + m
 
示例代码:
 1 import java.util.Scanner;
 2 
 3 public class Main {
 4     public static void main(String[] args) {
 5         Scanner sc = new Scanner(System.in);
 6         int n = sc.nextInt();
 7         int m = sc.nextInt();
 8         int appleNum =(int)Math.pow(n , n+1) - n*m + m;  //苹果被分了 n+1 次,吃了 n 次,最后分完后还剩 m 个
 9         System.out.println(appleNum);
10     }
11 }

 

以上是关于分苹果的算法的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯 算法训练 ALGO-121 猴子分苹果

算法历练之路——分苹果

C语言 · 分苹果

以下代码片段的算法复杂度

有人可以解释啥是 SVN 平分算法吗?理论上和通过代码片段[重复]

片段(Java) | 机试题+算法思路+考点+代码解析 2023