概率期望训练之四
https://www.luogu.org/problem/CF540D
前言:很简单的一道期望题
分析:
三维dp就行
记住期望反推:
dp[i,j,o]表示还有i个第一种没选,还有j个第二种没选,还有o个第三种还没选
很明显
if(i&&j) dp[i][j-1][o]+=(1.0*i*j/(i*j+j*o+i*o))*dp[i][j][o];
if(j&&o) dp[i][j][o-1]+=(1.0*j*o/(i*j+j*o+i*o))*dp[i][j][o];
if(i&&o) dp[i-1][j][o]+=(1.0*i*o/(i*j+j*o+i*o))*dp[i][j][o];
其中i×j+j×o+i×o表示选两种的总种类数
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
const int N=1e2+10;
int n,m,p;
double dp[N][N][N];
int main()
{
n=read(),m=read(),p=read();
dp[n][m][p]=1.0;
for(int i=n;i>=0;i--)
for(int j=m;j>=0;j--)
for(int o=p;o>=0;o--)
{
if(i&&j) dp[i][j-1][o]+=(1.0*i*j/(i*j+j*o+i*o))*dp[i][j][o];
if(j&&o) dp[i][j][o-1]+=(1.0*j*o/(i*j+j*o+i*o))*dp[i][j][o];
if(i&&o) dp[i-1][j][o]+=(1.0*i*o/(i*j+j*o+i*o))*dp[i][j][o];
}
double ed1=0,ed2=0,ed3=0;
for(int i=1;i<=n;i++) ed1+=dp[i][0][0];
for(int j=1;j<=m;j++) ed2+=dp[0][j][0];
for(int o=1;o<=p;o++) ed3+=dp[0][0][o];
printf("%.10f %.10f %.10f\n",ed1,ed2,ed3);
return 0;
}