/*
poj 3071
题目大意是
有2^n个球队
相邻两个队两两打淘汰赛
告诉你他们每个队打其他队胜利的概率
问那个队胜利的概率大
用dp[i][j]表示第i轮第j队胜利的概率
那么dp[i][j]的前提就是
i-1轮的时候j是赢的
而且第i轮赢了对方
接下来就是找到第i轮的时候
他的可能队手
通过二进制可以发现规律,所有高位是一样的,第i位刚好相反,所以用位运算可以巧妙解决,见代码
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define mod 1000000007
#define MAX 138
#define ll long long
#define PI acos(-1)
using namespace std;
double dp[MAX][MAX];
double p[MAX][MAX];
int main()
{
int n;
while(cin>>n)
{
if(n==-1)
break;
memset(dp,0,sizeof(dp));
memset(p,0,sizeof(p));
int tmp=pow(2.0,n);
for(int i=1;i<=tmp;i++)
for(int j=1;j<=tmp;j++)
cin>>p[i][j];
for(int i=1;i<=tmp;i++)//比赛是从第1场开始所以第0场胜率肯定为1
dp[0][i]=1.0;
for(int i=1;i<=n;i++)//第i场比赛
for(int j=1;j<=tmp;j++)
for(int k=1;k<=tmp;k++)
if((((j-1)>>(i-1))^(1))==((k-1)>>(i-1)))//第i-1场赢的双方是k和j然后第i场j赢k
dp[i][j]+=dp[i-1][k]*dp[i-1][j]*p[j][k];
double max=0.0;
int l;
for(int i=1;i<=tmp;i++)//找最大值
{
if(dp[n][i]>max)
{
max=dp[n][i];
l=i;
}
}
cout<<l<<endl;
}
return 0;
}
poj 3071
题目大意是
有2^n个球队
相邻两个队两两打淘汰赛
告诉你他们每个队打其他队胜利的概率
问那个队胜利的概率大
用dp[i][j]表示第i轮第j队胜利的概率
那么dp[i][j]的前提就是
i-1轮的时候j是赢的
而且第i轮赢了对方
接下来就是找到第i轮的时候
他的可能队手
通过二进制可以发现规律,所有高位是一样的,第i位刚好相反,所以用位运算可以巧妙解决,见代码
*/
#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <math.h>
#include <string.h>
#define mod 1000000007
#define MAX 138
#define ll long long
#define PI acos(-1)
using namespace std;
double dp[MAX][MAX];
double p[MAX][MAX];
int main()
{
int n;
while(cin>>n)
{
if(n==-1)
break;
memset(dp,0,sizeof(dp));
memset(p,0,sizeof(p));
int tmp=pow(2.0,n);
for(int i=1;i<=tmp;i++)
for(int j=1;j<=tmp;j++)
cin>>p[i][j];
for(int i=1;i<=tmp;i++)//比赛是从第1场开始所以第0场胜率肯定为1
dp[0][i]=1.0;
for(int i=1;i<=n;i++)//第i场比赛
for(int j=1;j<=tmp;j++)
for(int k=1;k<=tmp;k++)
if((((j-1)>>(i-1))^(1))==((k-1)>>(i-1)))//第i-1场赢的双方是k和j然后第i场j赢k
dp[i][j]+=dp[i-1][k]*dp[i-1][j]*p[j][k];
double max=0.0;
int l;
for(int i=1;i<=tmp;i++)//找最大值
{
if(dp[n][i]>max)
{
max=dp[n][i];
l=i;
}
}
cout<<l<<endl;
}
return 0;
}