1467. Probability of a Two Boxes Having The Same Number of Distinct Balls

这是一道概率题,假设输入balls表示所有的球数目。要讲球等分成两部分,a and b。要求sum(a)==sum(b) and sumtype(a)==sumtype(b),总共有多少种分割方式。

首先,总共的分割方式为perms(balls),比如balls = [1,2,3],1号颜色球有1个,2号颜色有2个,3号颜色有三个球。那么总共的扰动方式为6个位置中选1个,剩下5个位置中选2个,剩下3个位置放3个,总共是factor(sum(balls))/factor(ball[0])*factor(ball[1])*factor(ball[2])

那么所有这些方式中,有多少种成功的扰动呢?采用dfs遍历所有的a b包含的k个类别的样本数【很强的思路】,如果符合要求,那么包含的成功样本数为perm(a)*perm(b)。

class Solution {
public:
    
    
    vector<double> gainfactorialDp(int nums){
        vector<double> res;
        res.push_back(1);
        for(int i=1;i<=nums;i++){
            res.push_back(res[i-1]*i);
        }
        return res;
    }
    
    
    // count how many perms for a (ball nums)
    double perm(vector<int>& a, vector<double>& factors, int allballs){
        double res = factors[allballs];
        for(int i=0;i<a.size();i++){
            res /= factors[a[i]];
        }
        return res;
    }
    
    // find all cases for balls: [1,2,3]
    // [0,0,0], [0,0,1], [0,0,2], [0,0,3]
    // [0,1,0], [0,1,1], [0,1,2], [0,1,3]
    // [0,2,0], [0,2,1], [0,2,2], [0,2,3]
    double successperm = 0;
    void dfs(vector<int>& balls, vector<int>& a, vector<int>& b, int pos, vector<double>& factors){
        // a[pos], b[pos] set values from [0, balls[pos]]
        if (pos==balls.size()){
            // whether successful?? sum(a)==sum(b) sum(atype)==sum(btype)
            int suma = 0;
            int sumb = 0;
            int sumtypea = 0;
            int sumtypeb = 0;
            for(int i=0;i<a.size();i++){
                suma += a[i];
                sumb += b[i];
                if (a[i]>0){sumtypea++;}
                if (b[i]>0){sumtypeb++;}
            }
            if (suma==sumb&&sumtypea==sumtypeb){
                successperm += perm(a, factors, suma)* perm(b, factors, sumb);
            }
        }
        else{
            for(int i=0;i<=balls[pos];i++){
                a[pos] = i;
                b[pos] = balls[pos]-i;
                dfs(balls, a, b, pos+1, factors);
            }
        }
        
        
        
    }
    
    
    double getProbability(vector<int>& balls) {
        
        int allballs = 0;
        for(int i=0;i<balls.size();i++){allballs += balls[i];}
        
        vector<double> factors = gainfactorialDp(allballs);
        //for(int i=0;i<factors.size();i++){cout<<factors[i]<<endl;}
        double totalperms = perm(balls, factors, allballs);
        
        // count successful perms
        vector<int> a(balls.size(), 0);
        vector<int> b(balls.size(), 0);
        dfs(balls, a, b, 0, factors);
        
        //cout<<totalperms<<" "<<successperm<<endl;
        return successperm/totalperms;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值