Topcoder SRM 579 Level Three RockPaperScissors 题解
Topcoder SRM 579 Level Three RockPaperScissors 题解
首先玩家知道的只有\(a,b,c\)。而玩家希望通过\(a,b,c\)推出接下来剪刀石头布的概率。
以剪刀为例,概率为:
\[\mathbb{E}(\mathbb{P(s,a,b,c)}\times \frac{\sum_{i\not \in s}ScissorsProb(i) }{n-a-b-c}\times \frac{1}{n\choose {a+b+c}}|s\in \{1,2...n\},|s|=a+b+c,a+b+c\neq n)
\]
也就是每种状态概率的期望,其中\(\mathbb{P(s,a,b,c)}\)为\(s\)中有\(a,b,c\)个剪刀石头布的概率。
我们可以把前面的\(P\)看作后面$\sum $的系数。
可以另两个dp:
\(dp_{x,a,b,c}\)表示考虑了前\(x\)个,上述的结果是什么。
\(dp2_{x,a,b,c}\)表示系数总和。
转移也很简单。
code:
const int MAXN=51;
long double dp[2][MAXN][MAXN][MAXN][3],dp2[2][MAXN][MAXN][MAXN][3];
long double p[MAXN][3];
long double C(int A,int B){
long double ans=1;
rb(i,B+1,A){
ans*=i;
ans/=(i-B);
}
return ans;
}
class RockPaperScissors{
public:
double bestScore(vector<int> rockProb, vector<int> paperProb, vector<int> scissorsProb){
int n=rockProb.size();
rb(i,1,n) p[i][0]=rockProb[i-1]/300.0,p[i][1]=paperProb[i-1]/300.0,p[i][2]=scissorsProb[i-1]/300.0;
fill((long double*)dp,(long double*)dp+2*MAXN*MAXN*MAXN*3,0);
fill((long double*)dp2,(long double*)dp2+2*MAXN*MAXN*MAXN*3,0);
rep(i,3) dp[0][0][0][0][i]=0,dp2[0][0][0][0][i]=1;
rb(i,1,n){
fill((long double*)dp[i&1],(long double*)dp[i&1]+MAXN*MAXN*MAXN*3,0);
fill((long double*)dp2[i&1],(long double*)dp2[i&1]+MAXN*MAXN*MAXN*3,0);
rb(j,0,n) rb(k,0,n) rb(z,0,n) rep(l,3) if(dp2[(i&1)^1][j][k][z][l]!=0){
long double val=dp[(i&1)^1][j][k][z][l],val2=dp2[(i&1)^1][j][k][z][l];
dp[i&1][j+1][k][z][l]+=val*p[i][0];
dp2[i&1][j+1][k][z][l]+=val2*p[i][0];
dp[i&1][j][k+1][z][l]+=val*p[i][1];
dp2[i&1][j][k+1][z][l]+=val2*p[i][1];
dp[i&1][j][k][z+1][l]+=val*p[i][2];
dp2[i&1][j][k][z+1][l]+=val2*p[i][2];
dp[i&1][j][k][z][l]+=val+val2*p[i][l];
dp2[i&1][j][k][z][l]+=val2;
}
}
long double ans=0;
rb(j,0,n) rb(k,0,n) rb(z,0,n) {
if(dp2[n&1][j][k][z][0]==0) continue;
long double a,b,c;
a=dp[n&1][j][k][z][0];
b=dp[n&1][j][k][z][1];
c=dp[n&1][j][k][z][2];
int len=j+k+z;
if(n==len) continue;
long double comb=C(n,len);
a/=comb;
b/=comb;
c/=comb;
a/=n-len;
b/=n-len;
c/=n-len;
ans+=max(
max(
3.0*a+b
,
3.0*b+c
),
3.0*c+a
);
}
return ans;
}
}solver;