题意:
在一个岛上,有 r 个石头,s 个剪刀和 p 个布,遵循石头剪刀布的规则,他们之间相遇的概率相等,问他们存活的概率。
输入:
2 2 2
2 1 2
1 1 3
输出:
0.333333333333 0.333333333333 0.333333333333
0.150000000000 0.300000000000 0.550000000000
0.057142857143 0.657142857143 0.285714285714
分析:
用一个三维dp来表示岛上存活r,s,p的概率。初始dp[r][s][p]=1,转移:总共情况tol = i*j+i*k+j*k .
转移:
dp[i-1][j][k] += dp[i][j][k]*(i*k*1.0/sum);
dp[i][j-1][k] += dp[i][j][k]*(j*i*1.0/sum);
dp[i][j][k-1] += dp[i][j][k]*(j*k*1.0/sum);
最后留下两个物种在岛上时,就能确定谁能存活了,因为两者是相克的。最后在统一算就好。
代码:
三维dp
<span style="font-family: SimSun;"><span style="font-size:14px;">#include <bits/stdc++.h>
using namespace std;
const int maxn=105;
double dp[maxn][maxn][maxn];
int main()
{
int r,s,p;
cin >>r>>s>>p;
dp[r][s][p]=1.0; //初始状态1
for(int i=r; i>=1; i--)
{
for(int j=s; j>=1; j--)
{
for(int k=p; k>=1; k--)
{
double sum=i*j+i*k+j*k; //总情况
dp[i-1][j][k] += dp[i][j][k]*(i*k*1.0/sum);
dp[i][j-1][k] += dp[i][j][k]*(j*i*1.0/sum);
dp[i][j][k-1] += dp[i][j][k]*(j*k*1.0/sum);
}
}
}
double ans1=0.0,ans2=0.0,ans3=0.0;
for(int i=1; i<=100; i++)
{
for(int j=0; j<=100; j++)
{
ans1+=dp[i][j][0];
ans2+=dp[0][i][j];
ans3+=dp[j][0][i];
}
}
printf("%.10f %.10f %.10f\n",ans1,ans2,ans3);
return 0;
}
</span></span>