http://codeforces.com/problemset/problem/540/D
题意:
有r个石头,s个剪刀,p个布在一个岛上。问在足够长的时间里,石头,剪刀,布分别存活下来的概率。
思路:
定义dp[i][j][k]:还剩下i个石头,s个剪刀,p个布的概率。
初始dp[r][s][p] = 1;
转移:
总情况数:sum= i*j+j*k+i*k;
则dp[i-1][j][k] = (i*k/sum)*dp[i][j][k];dp[i][j-1][k] = (i*j/sum)*dp[i][j][k];dp[i][j][k-1] = (j*k/sum)*dp[i][j][k];
如果只剩下两种生物在岛上,则可以不用转移了。因为任意两种生物遇到可以肯定谁赢。
因此最后求和(看代码)。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <queue>
#include <stack>
#include <vector>
#include <map>
using namespace std;
typedef long long LL;
#define N 110
#define INF 0x3f3f3f3f
#define PI acos (-1.0)
#define EPS 1e-8
#define met(a, b) memset (a, b, sizeof (a))
double dp[N][N][N];
int main ()
{
int r, s, p;
while (scanf ("%d %d %d", &r, &s, &p) != EOF)
{
met (dp, 0);
dp[r][s][p] = 1.0;
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 + j*k + i*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] * k*j*1.0/sum;
}
double ans1 = 0, ans2 = 0, ans3 = 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;
}