分糖果算法题

分糖果,圣诞节到了,城堡里有k个小朋友,圣诞老人魔力袋里带了n件无差别的小礼物,请圣诞老人处理,将n个无差别的礼物分给k个小朋友的分法问题,给定n和k,输出总分法总数,并枚举所有的分法。其中 | 作为分隔符,每个小朋友的糖果用星号表示。

示例:3个糖果分给2个小朋友。总共有4种分法,枚举所有的分法如下:

*** |

** |*

* |**

| ***

java代码实现如下:

java 复制代码
/**
  * 计算将n个无差别糖果分给k个小朋友的分法总数(组合数学中的"stars and bars"问题)
  * 公式:C(n + k - 1, k - 1)
*/
public static int countDistributionWays(int n, int k) {
    // 使用组合数公式 C(n + k - 1, k - 1)
    return combination(n + k - 1, k - 1);
}
java 复制代码
/**
  * 计算组合数 C(n, k)
  */
private static int combination(int n, int k) {
        if (k < 0 || k > n) return 0;
        if (k == 0 || k == n) return 1;

        // 使用递推公式 C(n, k) = C(n-1, k-1) + C(n-1, k)
        int[][] dp = new int[n + 1][k + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= Math.min(i, k); j++) {
                if (j == 0 || j == i) {
                    dp[i][j] = 1;
                } else {
                    dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
                }
            }
        }

        return dp[n][k];
    }
java 复制代码
/**
  * 枚举所有分法
  */
public static List<List<Integer>> enumerateDistributions(int n, int k) {
        List<List<Integer>> result = new ArrayList<>();
        List<Integer> current = new ArrayList<>();

        // 初始化当前分配方案
        for (int i = 0; i < k; i++) {
            current.add(0);
        }

        backtrack(n, k, 0, 0, current, result);
        return result;
    }
java 复制代码
/**
  * 回溯法生成所有分配方案
  */
private static void backtrack(int n, int k, int index, int sum,
                                  List<Integer> current, List<List<Integer>> result) {
        // 如果已经分配完所有糖果且分配到所有小朋友
        if (index == k) {
            if (sum == n) {
                result.add(new ArrayList<>(current));
            }
            return;
        }

        // 当前小朋友可以分得的糖果数(从0到剩余糖果数)
        int remaining = n - sum;
        for (int i = 0; i <= remaining; i++) {
            current.set(index, i);
            backtrack(n, k, index + 1, sum + i, current, result);
        }
    }
java 复制代码
/**
  * 打印所有分配方案
  */
public static void printDistributions(List<List<Integer>> distributions) {
        for (int i = 0; i < distributions.size(); i++) {
            List<Integer> dist = distributions.get(i);
            StringBuilder format = new StringBuilder();
            for (int j = 0; j < dist.size(); j++) {
                int candyCount = dist.get(j);
                // 添加星号
                format.append("*".repeat(candyCount));
                // 添加分隔符(除了最后一个小朋友)
                if (j < dist.size() - 1) {
                    format.append("|");
                }
            }
            System.out.println(format.toString());
        }
    }
相关推荐
无心水1 小时前
【分布式利器:腾讯TSF】10、TSF故障排查与架构评审实战:Java架构师从救火到防火的生产哲学
java·人工智能·分布式·架构·限流·分布式利器·腾讯tsf
燃于AC之乐3 小时前
我的算法修炼之路--4 ———我和算法的爱恨情仇
算法·前缀和·贪心算法·背包问题·洛谷
Boilermaker19928 小时前
[Java 并发编程] Synchronized 锁升级
java·开发语言
Cherry的跨界思维8 小时前
28、AI测试环境搭建与全栈工具实战:从本地到云平台的完整指南
java·人工智能·vue3·ai测试·ai全栈·测试全栈·ai测试全栈
MM_MS8 小时前
Halcon变量控制类型、数据类型转换、字符串格式化、元组操作
开发语言·人工智能·深度学习·算法·目标检测·计算机视觉·视觉检测
独自破碎E9 小时前
【二分法】寻找峰值
算法
alonewolf_999 小时前
JDK17新特性全面解析:从语法革新到模块化革命
java·开发语言·jvm·jdk
一嘴一个橘子9 小时前
spring-aop 的 基础使用(啥是增强类、切点、切面)- 2
java
sheji34169 小时前
【开题答辩全过程】以 中医药文化科普系统为例,包含答辩的问题和答案
java
mit6.8249 小时前
位运算|拆分贪心
算法