0.500000
0.666667
0.500000
0.111111
概率dp。dp[x][y][a][b][c]:表示恐怖丧钟还能发射x次,加尔布鲁什还有y点体力,有a只生命值为三的奴隶主,b只生命值为2的
奴隶主,c只生命值为1的奴隶主的情况下,能杀死加尔布鲁什的概率。
记忆化搜索即可。
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int N = 25;
double dp[N][N][8][8][8];
int t, x, y, z;
void init()
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
for (int k = 0; k < 8; k++)
for (int kk = 0; kk < 8; kk++)
for (int kkk = 0; kkk < 8; kkk++)
dp[i][j][k][kk][kkk] = -1;
}
double dfs(int x, int y, int a, int b, int c)
{
if (dp[x][y][a][b][c] != -1)
return dp[x][y][a][b][c];
if (y == 0)
return dp[x][y][a][b][c] = 1.0;
if (x < y||!x) dp[x][y][a][b][c] = 0;
else
{
dp[x][y][a][b][c] = double(1) / (a + b + c + 1)*dfs(x - 1, y - 1, a, b, c);
if (a + b + c < 7)
{
if (a > 0) dp[x][y][a][b][c] += double(a) / (a + b + c + 1)* dfs(x - 1, y, a, b + 1, c);
if (b > 0) dp[x][y][a][b][c] += double(b) / (a + b + c + 1)* dfs(x - 1, y, a + 1, b - 1, c + 1);
if (c > 0) dp[x][y][a][b][c] += double(c) / (a + b + c + 1)* dfs(x - 1, y, a, b, c - 1);
}
else
{
if (a > 0) dp[x][y][a][b][c] += double(a) / (a + b + c + 1)* dfs(x - 1, y, a - 1, b + 1, c);
if (b > 0) dp[x][y][a][b][c] += double(b) / (a + b + c + 1)* dfs(x - 1, y, a, b - 1, c + 1);
if (c > 0) dp[x][y][a][b][c] += double(c) / (a + b + c + 1)* dfs(x - 1, y, a, b, c - 1);
}
}
return dp[x][y][a][b][c];
}
int main()
{
freopen("in.txt", "r", stdin);
scanf("%d", &t);
while (t--)
{
init();
scanf("%d%d%d", &x, &y, &z);
printf("%.6lf\n", dfs(x, y, z, 0, 0));
}
return 0;
}