描述
题解
这个题可以用暴力,因为数据很小,也可以用 dp d p ,初始化 16 16 只队伍,一共需要比赛四轮,所以我们可以通过前一轮的胜率推后一轮的,这里需要注意的是,每轮比赛的两个人在此轮分组中分布在前半部分一个,后半部分一个。
代码
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 20;
const int MAGIC = 16;
double F[MAXN][MAXN];
double dp[MAXN][5];
int main()
{
for (int i = 1; i <= MAGIC; i++)
{
for (int j = 1; j <= MAGIC; j++)
{
scanf("%lf", F[i] + j);
}
}
memset(dp, 0, sizeof(0));
// 第一轮胜出概率
for (int i = 1; i <= MAGIC; i++)
{
if (i % 2 == 1)
{
dp[i][1] = F[i][i + 1];
}
else
{
dp[i][1] = F[i][i - 1];
}
}
for (int i = 2; i <= 4; i++)
{
int sub = 1 << i;
for (int j = 1; j <= MAGIC; j++)
{
for (int k = 1; k <= MAGIC; k++)
{
// 在同一组才能开战
if ((j - 1) / sub == (k - 1) / sub)
{
// 假如 4 人一组,必须一个是 12 一个是 34
if ((j - 1) / (sub / 2) != (k - 1) / (sub / 2))
{
dp[j][i] += dp[j][i - 1] * dp[k][i - 1] * F[j][k];
}
}
}
}
}
for (int j = 1; j <= MAGIC; j++)
{
printf("%.10f%c", dp[j][4], j == MAGIC ? '\n' : ' ');
}
return 0;
}