POJ 3071:Football

Football
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3600   Accepted: 1844

Description

Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2n. In each round of the tournament, all teams still in the tournament are placed in a list in order of increasing index. Then, the first team in the list plays the second team, the third team plays the fourth team, etc. The winners of these matches advance to the next round, and the losers are eliminated. After n rounds, only one team remains undefeated; this team is declared the winner.

Given a matrix P = [pij] such that pij is the probability that team i will beat team j in a match determine which team is most likely to win the tournament.

Input

The input test file will contain multiple test cases. Each test case will begin with a single line containing n (1 ≤ n ≤ 7). The next 2n lines each contain 2n values; here, the jth value on the ith line represents pij. The matrix P will satisfy the constraints that pij = 1.0 − pji for all i ≠ j, and pii = 0.0 for all i. The end-of-file is denoted by a single line containing the number −1. Note that each of the matrix entries in this problem is given as a floating-point value. To avoid precision problems, make sure that you use either the double data type instead of float.

Output

The output file should contain a single line for each test case indicating the number of the team most likely to win. To prevent floating-point precision issues, it is guaranteed that the difference in win probability for the top two teams will be at least 0.01.

Sample Input

2
0.0 0.1 0.2 0.3
0.9 0.0 0.4 0.5
0.8 0.6 0.0 0.6
0.7 0.5 0.4 0.0
-1

Sample Output

2

Hint

In the test case above, teams 1 and 2 and teams 3 and 4 play against each other in the first round; the winners of each match then play to determine the winner of the tournament. The probability that team 2 wins the tournament in this case is:

P(2 wins)  P(2 beats 1)P(3 beats 4)P(2 beats 3) + P(2 beats 1)P(4 beats 3)P(2 beats 4)
p21p34p23 + p21p43p24
= 0.9 · 0.6 · 0.4 + 0.9 · 0.4 · 0.5 = 0.396.

The next most likely team to win is team 3, with a 0.372 probability of winning the tournament.


题意很明显,给出几支球队,给出他们相互之间胜负关系的概率,比赛机制就是两两对战淘汰,公式也在Hint中给出了。

所以问题就在  第几轮对战的双方的规律。我自己找出的规律就是 从0开始标记各支战队,第m支战队第n轮会碰到的对手是 将m化为二进制,从右往左开始算 第n位会不同,第n+1位开始要相同,其余位任意的所有数。

比方说:第3轮 第15支战队会碰到的对手是什么呢?

将15变为二进制是1111。第三轮,从右至左的第三位原来是1,现在变为0。

就是10XX,所以第15支战队第三轮会碰到的对手就是1000,1001,1010,1011这四支队。

这样的话,就按照Hint中给的思路求各支战队获得冠军的概率,比较谁最大输出即可。


代码:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

double value[1<<9][1<<9];
double dp[10][1<<9];

int main()
{
	//freopen("input.txt","r",stdin);
	//freopen("out.txt","w",stdout);
	int N,i,j,m;
	while(cin>>N)
	{
		if(N == -1)
			break;

		memset(value,0,sizeof(value));
		memset(dp,0,sizeof(dp));

		for(i=0;i<(1<<N);i++)
		{
			for(j=0;j<(1<<N);j++)
			{
				cin>>value[i][j];
			}
		}

		for(i=0;i<(1<<N);i++)
		{
			dp[0][i]=1;
		}

		for(i=1;i<=N;i++)
		{
			for(j=0;j<(1<<N);j++)
			{
				int temp=j;
				int pend= (temp>>(i-1))&1;
				int temp2=(temp>>(i))<<i;
				if(!pend)
				{
					temp2=temp2+(1<<(i-1));
				}
				
				int k;
				for(k=0;k<(1<<(i-1));k++)
				{
					if(j!=temp2)
					{
						dp[i][j] += dp[i-1][j]*dp[i-1][temp2]*value[j][temp2];
					}
					temp2++;
				}
			}
		}
		double max=0;
		int max_v=-1;
		for(i=0;i<(1<<N);i++)
		{
			if(dp[N][i]>=max)
			{
				max=dp[N][i];
				max_v=i+1;
			}
		}
		cout<<max_v<<endl;
	}
	return 0;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

原文地址:https://www.cnblogs.com/lightspeedsmallson/p/4785856.html