牛客35627C - Card
链接:https://ac.nowcoder.com/acm/contest/35627/C 知识点:概率期望 难度:蓝
题意
有 C 张金卡,S 张禁卡,B 张炸弹卡。 现在不放回地抽卡, 若取到金卡则继续抽卡, 若取到禁卡则立即停止抽卡, 若取到炸弹卡,则清空之前取到的所有金卡并立即停止抽卡。 求抽卡停止时,取到金卡数量的期望。
思路
考虑期望的线性可加性。
什么是期望的线性可加性?
需要注意的是:期望的线性可加性在使用前,要注意确保这些事件彼此相互独立,互不影响。
这些题目可以让你练手: CF280C、洛谷4316、洛谷3232、洛谷6835
事件的确定、概率的计算
既然是求取到金卡数量的期望,咱们一定要从金卡下手。 禁卡、爆炸卡...太复杂,咱们不妨先将所有卡分为两类: 好卡(金卡)和坏卡(禁卡和爆炸卡) 就以好卡的最小单位,1张好卡下手,设事件为这张好卡在坏卡被抽到之前 被抽到, 那么在这种情况下,这张卡是一定能对期望做出 的贡献。 此事件发生的概率
为什么是? 因为这是不可放回地抽。
如果,如果,炸弹卡不具备清空金卡的作用,那么答案就是 注意:实际上炸弹能清空金卡,那么如果很不幸最后抽到的那一张为炸弹卡(发生的概率为 ),那么直接就是 。 所以,最终的答案
代码
#include <cstdio>
#include <iostream>
#define int long long
const int N = 1e6+10;
const int MOD = 1e9+7;
using namespace std;
long long POW(long long a,long long b)
{
long long ans=1;
while(b>0)
{
if(b&1)
{
ans*=a, ans%=MOD;
}
a*=a, a%=MOD;
b>>=1;
}
return ans;
}
int Inv(int a,int b)
{
return a*POW(b, MOD-2)%MOD;
}
int Gold,Proh,Bomb;
int T;
void Solve()
{
if(Proh==0&&Bomb==0)
{
printf("%lld\n",Gold);
return;
}
//禁止牌在炸弹牌之前被抽到
int tmp1 = Inv(Proh, (Proh+Bomb)%MOD);
//某一张金牌在禁止牌和炸弹牌之前被抽到
int tmp2 = Inv(1, (Proh+Bomb+1)%MOD);
int ans = Gold * tmp2 % MOD * tmp1 % MOD;
printf("%lld\n",ans);
}
signed main()
{
scanf("%lld",&T);
while (T--)
{
scanf("%lld %lld %lld",&Gold,&Proh,&Bomb);
Solve();
}
return 0;
}