思路:入门级别的概率dp,求概率一般是顺推。
dp[i] [ j ] 代表着第i轮比赛,第j个队获胜的概率。
dp[i] [ j] = dp[i] [j] + d[i-1] [j] * dp[i-1] [k] * p[j] [k]
同时运用了位运算来保证两个队伍相邻。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 1e4+100;
double p[maxn][maxn], dp[maxn][maxn];
int main()
{
int n;
while(scanf("%d", &n) == 1 && n != -1)
{
int len = 1<<n;
for(int i = 1;i<=len;i++)
{
for(int j =1;j<=len;j++)
{
scanf("%lf", &p[i][j]);
dp[i][j] = 0;
}
}
for(int i = 1;i<=len;i++)dp[0][i] = 1.0;
for (int i = 1; i <= n; ++i){//正在进行第i次(大场)比赛!
for (int j = 1; j <= len; ++j){
for (int k = 1; k <= len; ++k){
if ((((j-1) >> (i-1)) ^ 1) == ((k-1) >> (i-1)))//判断能否进行比赛(是否相邻!) 注意优先级问题~~
dp[i][j] += dp[i-1][j] * dp[i-1][k] * p[j][k];
}
}
}
double maxx = 0.0;
int maxi = 0;
for(int i = 1;i<=len;i++)
{
if(dp[n][i] > maxx)
{
maxx = dp[n][i];
maxi = i;
}
}
printf("%d\n",maxi);
}
return 0;
}