POJ3071 (probability DP)

                                                             FOOTBALL

 Meaning of the questions:

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 

subject to the effect: give your team n-th power of 2, adjacent to the two teams twenty-two proceeds knockout, ask your probability of which only the last team to win the most.
The subject can use probabilistic thinking to solve dp, dp [i] [j] represents the probability that the j-win teams in the i-th innings, then there is the following code:
//num表示队伍的总数 
for(int i=1;i<=num;i++) 
dp[0][i]=1; // 每只队伍在刚开始比赛的时候(第0局)获胜的概率为1 
        for(int i=1;i<=n;i++)  //表示总共进性n局 
        {
            for(int j=1;j<=num;j++) //表示第i局j获胜 
            {
                for(int k=1;k<=num;k++)//表示第i局k失败 
                {
                  //递推公式 
                }
            }
        }

然后就是递推公式,dp[i][j]+=dp[i-1][j]*dp[i-1][k]*map[j][k].此递推公式很好理解,j如果想在第i局中打败k的

话,其获胜的概率就等于在上一局中j获胜的概率*上一局中k获胜的概率*j打败k的概率,然而只有当一定条件

下j和k才会相遇,假设总共有八只队伍,第一只和第三只队伍只可能在第二局中相遇,第一只和第八只只可能在

第三局中相遇,这个问题可以用if来进行以此判断,判断条件在代码中

#include<iostream>
#include<cmath>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
    double map[200][200],dp[10][200];
    int n;
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));
        if(n==-1) break;
        int num=1<<n;
        for(int i=1;i<=num;i++)
      {
        for(int j=1;j<=num;j++) cin>>map[i][j];
      }
        for(int i=1;i<=num;i++) dp[0][i]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=num;j++)
            {
                for(int k=1;k<=num;k++)
                {
                    if ((((j-1) >> (i-1)) ^ 1) == ((k-1) >> (i-1)))
                        dp[i][j] += dp[i-1][j] * dp[i-1][k] * map[j][k];
                }
            }
        }
      double max=0.0;
      int ans;
      for(int i=1;i<=num;i++)
      {
          if(dp[n][i]>max)
          {
              max=dp[n][i];
              ans=i;
        }
      }
      cout<<ans<<endl; 
    }    
    return 0;
} 

___________________________________________________________________________________________________________________





Guess you like

Origin www.cnblogs.com/tombraider-shadow/p/10959836.html