题意:
有r个石头,s个剪刀,p个布在一个岛上。问在足够长的时间里,石头,剪刀,布分别存活下来的概率。
思路:
感谢铭神指导!
定义dp[i][j][k]:还剩下i个石头,s个剪刀,p个布的概率。
初始dp[r][s][p] = 1;
转移:
总情况数:tol = i*j+j*k+i*k;
则dp[i-1][j][k] = (i*k/tol)*dp[i][j][k];dp[i][j-1][k] = (i*j/tol)*dp[i][j][k];dp[i][j][k-1] = (j*k/tol)*dp[i][j][k];
如果只剩下两种生物在岛上,则可以不用转移了。因为任意两种生物遇到可以肯定谁赢。
因此最后求和(看代码)。
code:
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
typedef long long LL;
double dp[N][N][N];
int r, s, p;
int main() {
cin>>r>>s>>p;
dp[r][s][p] = 1;
for(int i = r; i >= 1; i--) {
for(int j = s;j >= 1;j --) {
for(int k = p;k >= 1; k--) {
if(dp[i][j][k] == 0) continue;
int tol = i*j+i*k+j*k;
double tmp = 1.0*i*j/tol;
dp[i][j-1][k] += dp[i][j][k]*tmp;
tmp = 1.0*i*k/tol;
dp[i-1][j][k] += dp[i][j][k]*tmp;
tmp = 1.0*j*k/tol;
dp[i][j][k-1] += dp[i][j][k]*tmp;
}
}
}
double res = 0;
for(int i = 1;i <= r; i++)
for(int j = 0;j <= s; j++)
res += dp[i][j][0];
printf("%.9f", res);
res = 0;
for(int i = 1;i <= s; i++)
for(int j = 0;j <= p; j++)
res += dp[0][i][j];
printf(" %.9f", res);
res = 0;
for(int i = 1;i <= p; i++)
for(int j = 0;j <= r; j++)
res += dp[j][0][i];
printf(" %.9f\n", res);
return 0;
}