POJ 3071 Football 【概率DP】

Football

Football

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 3734   Accepted: 1908

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.

题意:这个题是给你一个2^N的一个概率矩阵p , p[i][j]用来表示第i队赢第j队的概率,足球比赛是根据编号由小到大来两两比赛的,问你最有可能最后赢的队伍编号。

分析:队伍两两之间进行比赛,直到得到Winner,这个过程是需要N层比赛的【我想不出什么高级的词汇了,就用层来说吧,语文不好,不要嘲笑~】,每一层有若干双 队伍 同时进行比赛。然后是根据编号两两比赛的,这个时候不妨画出一个图出来,我们可以发现,这就是一个二叉树嘛。

首先,设状态 dp[i][j] 表示第i层比赛第j号队伍赢的概率。

然后,设状态转移方程:dp[i][j] = dp[i-1][j] * ∑(dp[i-1][k]*p[j][k]),ps:k∈(二叉树上(i,j)除了(i-1,j)的另外一个子节点以下的所有叶子节点的编号),说得确实有点拗口,但是只要画出图来,就非常好理解。

接下来,考虑边界情况,显然dp[0][j] = 0,或者说dp[1][j] = p[j][(j-1)^1+1]   【另外一种写法是dp[i][j] = p[j][j&1?j+1:j-1],用哪种凭个人喜好吧】,j∈(1,1<<N)。

最后,只需要遍历所有dp[N][j] ,j∈(1,1<<N),求最大的概率即可。

/**
 *  Memory:444KB    Time:79ms
 *  Author:__Xiong  2015/7/27
 */
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 7+1;
const int maxm = (1<<maxn);
int N,M,ans;
double pMax,p[maxm][maxm],dp[maxn][maxm];
int main()
{
    //freopen("input.in","r",stdin);
    while(~scanf("%d",&N))
    {
        if(N == -1) break;
        M = (1<<N);
        for(int i = 1; i <= M; i++)
        {
            for(int j = 1; j <= M; j++)
            {
                scanf("%lf",&p[i][j]);
            }
        }
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= N; i++)
        {
            for(int j = 1; j <= M; j++)
            {
                if(i == 1)
                {
                    dp[1][j] = p[j][j&1?j+1:j-1];
                    continue;
                }
                for(int k = 1; k <= M; k++)
                {
                    int a = (j-1)>>(i-1),b = (k-1)>>(i-1);
                    if(a&1) a--;
                    else a++;
                    if(a == b)
                        dp[i][j] += dp[i-1][j]*dp[i-1][k]*p[j][k];
                }
            }
        }
        pMax = 0;
        ans = 0;
        for(int i = 1; i <= M; i++)
        {
            if(pMax < dp[N][i])
            {
                ans = i;
                pMax = dp[N][i];
            }
        }
        printf("%d\n",ans);

    }
    return 0;
}

另外,挂上基神的代码吧。

// 亲测:Memory:1080KB     Time:79ms
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MX = 150 + 5;
#define For(i,x,y) for(int i=x;i<=y;i++)
#define Mem(x,y) memset(x,y,sizeof(x))
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define root 1,n,1
int n;
double A[MX][MX];
double dp[MX << 2][MX];
void solve(int l, int r, int rt)
{
    if(l == r)
    {
        dp[rt][l] = 1;
        return;
    }
    int m = (l + r) >> 1;
    solve(lson);
    solve(rson);
    For(x, l, r)
    {
        if(x <= m)
        {
            For(i, m + 1, r)
            {
                dp[rt][x] += dp[rt << 1 | 1][i] * A[x][i];
            }
            dp[rt][x] *= dp[rt << 1][x];
        }
        else
        {
            For(i, l, m)
            {
                dp[rt][x] += dp[rt << 1][i] * A[x][i];
            }
            dp[rt][x] *= dp[rt << 1 | 1][x];
        }
    }
}
int main()
{
    //freopen("input.in", "r", stdin);
    int n;
    while(~scanf("%d", &n), n >= 0)
    {
        Mem(dp, 0);
        n = 1 << n;
        For(i, 1, n)
        {
            For(j, 1, n)
            {
                scanf("%lf", &A[i][j]);
            }
        }
        solve(root);
        double Max = 0;
        int ans;
        For(i, 1, n)
        {
            if(dp[1][i] > Max)
            {
                Max = dp[1][i];
                ans = i;
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

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

时间: 2024-10-20 03:55:44

POJ 3071 Football 【概率DP】的相关文章

[ACM] POJ 3071 Football (概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2875   Accepted: 1462 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

poj 3071 Football (概率DP水题)

G - Football Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u Submit Status Description Consider a single-elimination football tournament involving 2n teams, denoted 1, 2, …, 2n. In each round of the tournament, all teams

POJ 3071 Football (概率DP)

题意:给定 2的n次方 个团队对每个队的战胜的概率,一块要打 n 场,每场都是 1 对 2, 2 对 3,每次都取赢的一方,问你最后谁是冠军的概率最大. 析:dp[i][j] 表示 第 i 场 j 胜的概率,每次只要算 i 相邻的且不是已经打过的 2 i-1次方个队,最后再选出概率最大的就好. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include &l

poj 3071 简单概率dp

题意很清晰,就是问最有可能获得冠军的队伍. 需要注意的是每轮比赛中,每个队都是和自己旁边的一个队比赛,采用淘汰赛制,所以需要决定第i轮的时候j队可以和哪些队比赛,然后求概率dp即可. 状态转移方程: dp[i][j] += dp[i - 1][j] * dp[i - 1][k] * p[j][k]; dp[i][j]表示第i轮j队获胜的概率 = 第i-1轮j队获胜的概率 * 第i-1轮k队获胜的概率 * j队打败k队的概率(之和). 前提是j和k在第i轮可能遇到. 判断方法: ( j >> (

POJ 3071 Football(简单 概率DP)

Football 原文链接:http://blog.csdn.net/xuechelingxiao/article/details/38520105 大意:2^n 个球队进行单场淘汰赛,每两只球队之间比赛会有胜负的概率,问最后谁夺冠的概率最大. 思路:简单的概率DP问题,主要是怎么处理哪两个球队比赛的问题. DP方程为 dp[i][j] = ∑(dp[i-1][j]*dp[i-1][k]*p[j][k]); //dp[i][j]表示第 i 轮的时候,第 j 支队伍赢的概率.. 对于其中位运算,可

POJ 3071 Football (动态规划-概率DP)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2768   Accepted: 1412 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

poj 3071 Football (概率 dp)

链接:poj 3071 题意:有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位开始所有高位是一样的,可以利用位运算判断是否为对手 状

POJ 3071 Football (概率DP)

概率dp的典型题.用dp[j][i]表示第j个队第i场赢的概率.那么这场要赢就必须前一场赢了而且这一场战胜了可能的对手.这些都好想,关键是怎么找出当前要算的队伍的所有可能的竞争对手?这个用异或来算,从队伍编号的二进制表示中可以看出规律来(从二进制和相关运算里找规律也是一个重要的思考角度). #include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<s

POJ 3071 Football

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 l

POJ 3071-Football(概率dp)

Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3145   Accepted: 1591 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