Bonus Card题解
这么好的题居然没有题解!qwq
先看 Dmitry 参与一类抽选并被选中的概率,答案是
设计状态
肯定有一位是轮数,另外我们需要知道一类二类各有多少人以及被抽中的概率,
所以
考虑状态转移
如果下一轮选中的是二类
该状态发生的概率是
如果下一轮选中的是一类
该状态发生的概率是
注意 :一类被抽中的概率是二类的两倍,使一类权值为
对于具体的统计答案,并不是简单的
因为剩下这么多人,只有人数分之一的概率使得被抽中的是 Dmitry。
Code:
//概率DP (看数据范围得知是n方)
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=3010;
double n,A,B,f[N][N][2],ans1,ans2;
int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//其实根本不用快读
signed main()
{
n=read(),A=read(),B=read();
// Dmitry本身不算在 A B 里面
if(n>A+B){puts("1.0");puts("1.0");return 0;}
f[0][0][0]=f[0][0][1]=1;
for(int i=0;i<n;i++)
for(int j=0;j<=i&&j<=A;j++)
{
if(f[i][j][0]==0) continue;
if(A-j>0) f[i+1][j+1][0]+=f[i][j][0]*(2*(A-j)/(2*(A-j)+(B-i+j)+2));
if(B-i+j>0) f[i+1][j][0]+=f[i][j][0]*((B-i+j)/(2*(A-j)+(B-i+j)+2));
}
for(int i=0;i<n;i++)
for(int j=0;j<=i&&j<=A;j++) ans1+=2*f[i][j][0]/(2*(A-j)+(B-i+j)+2);
printf("%.16lf\n",ans1);
for(int i=0;i<n;i++)
for(int j=0;j<=i&&j<=A;j++)
{
if(f[i][j][1]==0) continue;
if(A-j>0) f[i+1][j+1][1]+=f[i][j][1]*(2*(A-j)/(2*(A-j)+(B-i+j)+1));
if(B-i+j>0) f[i+1][j][1]+=f[i][j][1]*((B-i+j)/(2*(A-j)+(B-i+j)+1));
}
for(int i=0;i<n;i++)
for(int j=0;j<=i&&j<=A;j++) ans2+=f[i][j][1]/(2*(A-j)+(B-i+j)+1);
printf("%.16lf\n",ans2);
return 0;
}
感谢管理员耐心指正(鞠躬orz)