最近训练时写的比赛,当时b题没写,事后补一下,看了下题解,想写下自己的解释
原题解:2016湖南湘潭邀请赛题解:2016年“长城信息”杯中国大学生程序设计比赛中南地区邀请赛(迟来的题解)
题目:
大意是:有a个红球,b个绿球,c个蓝球,放在箱子里,每次从箱子中不放回的拿来一个,拿完一种颜色的所有的球,游戏就结束。根据拿完的球判断是几等奖,把所有红球拿完1等奖,所有绿球拿完2等奖,所有蓝球拿完3等奖,求每种奖项概率
当时感觉没什么思路,看了题解后大概明白了
先求一等奖的概率吧
假设我们把所有的球都拿完(即使把某种颜色的球全部拿完后,我们也接着拿,把所有球都拿完)
那么我们拿到一等奖的评判标准是什么,是我最后拿到的球的颜色不是红球,并在此基础上,去掉所有最后一个球同色球之后,最后一个拿到的球仍然不是红球,接下来我用a代表红球,b代表绿球,c代表蓝球
假设3红,3绿,3蓝
aababbccc 最后一个拿到的球是c,除去c之后最后拿到的球是b,一等奖条件成立
aabbbccac 最后一个拿到的球是c,除去c之后最后一个拿到的是a球,很明显不符合一等奖
bbabcccaa 最后一个球是红球,不符合一等奖要求
最后拿到的球的颜色不是红球,并在此基础上,去掉所有最后一个球的同色球之后,最后一个拿到的球仍然不是红球,满足这个条件的一定是一等奖,不满足的一定不是一等奖
那么根据这个规则,我们就可以把获得一等奖的概率这个问题就转换成,最后一个球不是红球,并且去掉所有最后一个球的同色球后,最后一个球仍然不是红球的概率
由于正常的来求这个也不太好求,所以我们可以把抽取的顺序倒置过来,比如我们把aababbccc
换成cccbbabaa,这样求最后一个球的概率就变成求第一个球的概率了,好算很多
于是我们分类讨论,当第一个球我们抽到绿球的概率是 b/(a+b+c)
去掉所有绿球后,我们第一个球得到蓝球的概率是 c/(a+c)
同理当第一个球我们抽到蓝球的概率是 c/(a+b+c)
去掉所有蓝球后,我们第一个球得到绿球的概率是 b/(a+b)
那么此时把两种情况概率相加,我们就得到了最后一个球不是红球,并且去掉所有最后一个球的同色球后,最后一个球仍然不是红球的概率,即一等奖概率
二等奖,三等奖计算也是如此
代码:
#include <iostream>
using namespace std;
typedef long long ll;
int f[1010][2020];
ll gcd(ll a,ll b)
{
ll r=0;
while(b)
{
r=a%b;
a=b;
b=r;
}
return a;
}
void alg(ll a,ll b,ll c)
{
ll sum1=b*c*(2*a+b+c);
ll sum2=(a+b+c)*(a+b)*(a+c);
ll z=gcd(sum1,sum2);
printf("%lld/%lld",sum1/z,sum2/z);
}
int main()
{
int a,b,c;
while(cin>>a>>b>>c)
{
alg(a,b,c);
cout<<' ';
alg(b,a,c);
cout<<' ';
alg(c,a,b);
cout<<endl;
}
return 0;
}