题意:有2^n个队,相邻的两两打淘汰赛,n轮后必定会决出冠军,
求最后哪个队夺冠的概率最大
分析:dp[i][j]表示第i轮的时候,第j去支队伍赢的概率
则dp[i][j]的前提就是i-1轮的时候,j是赢的,且第i轮赢了对方
接下来就是找到第i轮的时候,他的可能队手(难点)
所有对手的编号为1-2^n,通过二进制可以发现规律,
若第j队和对手k队在第i轮比赛,那么(j-1)和(k-1)二进制第i位刚好相反,
从i+1位开始所有高位是一样的,可以利用位运算判断是否为对手
状态方程为:
dp[i][j]=sigma(dp[i-1][j]*dp[i-1][k]*p[j][k])
#include<stdio.h>
#include<string.h>
int main()
{
double p[150][150],dp[150][150];
int n,i,j,k;
while(scanf("%d",&n)!=EOF){
if(n==-1)
break;
int m=1<<n;
for(i=1;i<=m;i++)
for(j=1;j<=m;j++)
scanf("%lf",&p[i][j]);
memset(dp,0,sizeof(dp));
for(i=1;i<=m;i++)
dp[0][i]=1.0;
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
for(k=1;k<=m;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 max_p=0;
int ans=0;
for(i=1;i<=m;i++)
if(dp[n][i]>max_p){
max_p=dp[n][i];
ans=i;
}
printf("%d\n",ans);
}
return 0;
}