遗世独立的理想乡

Football

Time Limit:1000MSMemory Limit:65536K

Total Submissions:3729Accepted:1905

Description

Consider a single-elimination football tournament involving 2nteams, 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. Afternrounds, only one team remains undefeated; this team is declared the winner.

Given a matrixP= [pij] such thatpijis the probability that teamiwill beat teamjin 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 containingn(1 ≤n≤ 7). The next 2nlines each contain 2nvalues; here, thejth value on theith line representspij. The matrixPwill satisfy the constraints thatpij= 1.0 pjifor alli≠j, andpii= 0.0 for alli. 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 thedoubledata type instead offloat.

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

20.0 0.1 0.2 0.30.9 0.0 0.4 0.50.8 0.6 0.0 0.60.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.

编号分别为1、2、3……2^n的2^n个队伍参加比赛,每一轮相邻的两两比赛,胜者晋级下一轮,负者淘汰,直到只剩下一支队伍。

基本思路:dp[i][j]表示第i轮比赛j号队胜利的概率,第i轮j要获胜,首先第(i-1)轮j要获胜,(所以dp[0][j]要初始化为1),用k表示能与k在第i轮比赛中相遇的对手,而且如果j与k要相遇,k也必须在第(i-1)轮中获胜,所以状态转移方程为dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k],注意,是相加,即把遇到每个对手且获胜相加就是j在这一轮获胜的总概率。

状态转移方程得到了,下一个点就是找到第i轮j可能遇到的对手。有很多种方法,比如第一份代码就是通过标记记录j与k是否在第i轮之前交手,如果vis[j][k]=1,,那么他们必定有一个被淘汰,就不可能在第i轮相遇,(k的范围的获得详见代码);第二份代码判断的方式就比较简单了,通过位来进行判断,自己可以带几组数据试一试,规律基本就能发现了。

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int MAXN=(1<<7)+5;//注意括号double p[MAXN][MAXN],dp[10][MAXN];int vis[MAXN][MAXN];int n;int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endif // ONLINE_JUDGEwhile(scanf("%d",&n)!=EOF&&n!=-1){int people=1<<n;for(int i=0;i<people;i++)for(int j=0;j<people;j++)scanf("%lf",&p[i][j]);memset(dp,0,sizeof(dp));memset(vis,0,sizeof(vis));for(int i=0;i<people;i++){dp[0][i]=1;vis[i][i]=1;}for(int i=1;i<=n;i++)for(int j=0;j<people;j++){if(i==1){dp[i][j]=p[j][j/2*4+1-j];vis[j][j/2*4+1-j]=1;}else{int s=j/(1<<i)*(1<<i),e=j/(1<<i)*(1<<i)+(1<<i);//不难发现第i轮可能与j交手的人一共有(1<<i)个(包含j本身)//因此可以在第i轮时把队伍按照(1<<i)个一组进行分组,接下来就只要找到j的分组//所以s=j/(1<<i)*(1<<i)可以求出可能与j交手的人的最小编号//e=j/(1<<i)*(1<<i)+(1<<i)是最大编号for(int k=s;k<e;k++)if(!vis[j][k])//如果没有交过手{vis[j][k]=1;dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];}}}double maxx=-1;int win=0;for(int i=0;i<people;i++){if(dp[n][i]>maxx){maxx=dp[n][i];win=i+1;}}printf("%d\n",win);}return 0;}#include<stack>#include<queue>#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#pragma commment(linker,"/STACK: 102400000 102400000")#define lson a,b,l,mid,cur<<1#define rson a,b,mid+1,r,cur<<1|1using namespace std;const double eps=1e-6;const int MAXN=(1<<7)+5;double p[MAXN][MAXN],dp[10][MAXN];int n;int main(){#ifndef ONLINE_JUDGEfreopen("in.txt","r",stdin);#endif // ONLINE_JUDGEwhile(scanf("%d",&n)&&n!=-1){int people=1<<n;for(int i=0;i<people;i++)for(int j=0;j<people;j++)scanf("%lf",&p[i][j]);memset(dp,0,sizeof(dp));for(int i=0;i<people;i++)dp[0][i]=1;for(int i=1;i<=n;i++)for(int j=0;j<people;j++)for(int k=0;k<people;k++)if(((j>>(i-1))^1)==(k>>(i-1)))//通过二进制来判断在第i轮是否能相遇dp[i][j]+=dp[i-1][j]*dp[i-1][k]*p[j][k];double maxx=-1;int win=0;for(int i=0;i<people;i++){//printf("%.3lf ",dp[n][i]);if(dp[n][i]>maxx){maxx=dp[n][i];win=i+1;}}printf("%d\n",win);}return 0;}

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

去了不同的地方,看了不同的风景,知道了不同的事,

遗世独立的理想乡

相关文章:

你感兴趣的文章:

标签云: