• 概率-dfs-5427. 两个盒子中球的颜色数相同的概率


    2020-05-31 17:21:08

    问题描述:

    桌面上有 2n 个颜色不完全相同的球,球上的颜色共有 k 种。给你一个大小为 k 的整数数组 balls ,其中 balls[i] 是颜色为 i 的球的数量。

    所有的球都已经 随机打乱顺序 ,前 n 个球放入第一个盒子,后 n 个球放入另一个盒子(请认真阅读示例 2 的解释部分)。

    注意:这两个盒子是不同的。例如,两个球颜色分别为 a 和 b,盒子分别为 [] 和 (),那么 [a] (b) 和 [b] (a) 这两种分配方式是不同的(请认真阅读示例 1 的解释部分)。

    请计算「两个盒子中球的颜色数相同」的情况的概率。

    示例 1:

    输入:balls = [1,1]
    输出:1.00000
    解释:球平均分配的方式只有两种:
    - 颜色为 1 的球放入第一个盒子,颜色为 2 的球放入第二个盒子
    - 颜色为 2 的球放入第一个盒子,颜色为 1 的球放入第二个盒子
    这两种分配,两个盒子中球的颜色数都相同。所以概率为 2/2 = 1 。
    示例 2:

    输入:balls = [2,1,1]
    输出:0.66667
    解释:球的列表为 [1, 1, 2, 3]
    随机打乱,得到 12 种等概率的不同打乱方案,每种方案概率为 1/12 :
    [1,1 / 2,3], [1,1 / 3,2], [1,2 / 1,3], [1,2 / 3,1], [1,3 / 1,2], [1,3 / 2,1], [2,1 / 1,3], [2,1 / 3,1], [2,3 / 1,1], [3,1 / 1,2], [3,1 / 2,1], [3,2 / 1,1]
    然后,我们将前两个球放入第一个盒子,后两个球放入第二个盒子。
    这 12 种可能的随机打乱方式中的 8 种满足「两个盒子中球的颜色数相同」。
    概率 = 8/12 = 0.66667
    示例 3:

    输入:balls = [1,2,1,2]
    输出:0.60000
    解释:球的列表为 [1, 2, 2, 3, 4, 4]。要想显示所有 180 种随机打乱方案是很难的,但只检查「两个盒子中球的颜色数相同」的 108 种情况是比较容易的。
    概率 = 108 / 180 = 0.6 。
    示例 4:

    输入:balls = [3,2,1]
    输出:0.30000
    解释:球的列表为 [1, 1, 1, 2, 2, 3]。要想显示所有 60 种随机打乱方案是很难的,但只检查「两个盒子中球的颜色数相同」的 18 种情况是比较容易的。
    概率 = 18 / 60 = 0.3 。
    示例 5:

    输入:balls = [6,6,6,6,6,6]
    输出:0.90327

    提示:

    1 <= balls.length <= 8
    1 <= balls[i] <= 6
    sum(balls) 是偶数
    答案与真实值误差在 10^-5 以内,则被视为正确答案

    问题求解:

    暴力枚举放在每个框中球的个数。

        public double getProbability(int[] balls) {
            double total = get_cnt(balls);
            double sub_total = dfs(0, balls, new int[balls.length], new int[balls.length], 0, 0, 0, 0);
            return sub_total / total;
        }
        
        
        private double dfs(int idx, int[] balls, int[] left, int[] right, int lcnt, int rcnt, int ltot, int rtot) {
            if (idx >= balls.length) {
                if (ltot == rtot && lcnt == rcnt) return get_cnt(left) * get_cnt(right);
                return 0;
            }
            double res = 0;
            for (int i = 0; i <= balls[idx]; i++) {
                left[idx] = i;
                right[idx] = balls[idx] - i;
                res += dfs(idx + 1, balls, left, right, i > 0 ? lcnt + 1 : lcnt, balls[idx] - i > 0 ? rcnt + 1 : rcnt, ltot + i, rtot + balls[idx] - i);
            }
            return res;
        }
        
        
        private double get_cnt(int[] nums) {
            double res = 0;
            int sum = 0;
            for (int num : nums) sum += num;
            res = fact(sum);
            for (int num : nums) res /= fact(num);
            return res;
        }
        
        private double fact(int n) {
            double res = 1;
            for (int i = 2; i <= n; i++) res *= i;
            return res;
        }
    

      

  • 相关阅读:
    大量建置账号
    MYSQL远程登录权限设置
    设置mysql远程连接root权限
    阿里云服务器上安装mysql的心路历程(博友们进来看看哦)
    Array.Copy
    C#如何判断两个数组相等
    CentOS6.5下编译安装mysql5.6.19
    Linux下卸载和安装MySQL[rpm包]
    查看Linux磁盘空间大小
    C# 数组CopyTo
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/13019943.html
Copyright © 2020-2023  润新知