POJ3071-Football(概率DP+滚动数组)

Football

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2769   Accepted: 1413

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
简单的概率题:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>
using namespace std;
const int  maxn = 1 << 8;
double p[maxn][maxn];
int n,all;
double dp[2][maxn];
int main(){

    while(cin >> n&&n!=-1){
        all = (1 << n);
        for(int i = 1; i <= all; i++)
            dp[1][i] = 1;
        for(int i = 1; i <= all; i++)
            for(int j = 1; j <= all; j++)
                cin >> p[i][j];
        for(int i = 0; i < n; i++){
            int d = 1<<i;
            for(int k = 1; k <= all; k++){
                dp[0][k] = dp[1][k];
                dp[1][k] = 0;
            }

            int sta=1,ed=sta+d;
            while(ed <= all){
                for(int k = sta; k < ed; k++){
                    for(int a = ed; a < ed+d; a++){
                        dp[1][k] += dp[0][k]*dp[0][a]*p[k][a];
                        dp[1][a] += dp[0][a]*dp[0][k]*p[a][k];
                    }
                }
                sta += 2*d;
                ed = sta+d;
            }
        }
        double ans = dp[1][1];
        int idx = 1;
        for(int i = 2; i <= all; i++){
            if(dp[1][i] > ans){
                ans = dp[1][i];
                idx = i;
            }
        }
        cout<<idx<<endl;
    }
    return 0;
}

POJ3071-Football(概率DP+滚动数组),布布扣,bubuko.com

时间: 2024-10-10 07:49:49

POJ3071-Football(概率DP+滚动数组)的相关文章

[ACM] HDU 4576 Robot (概率DP,滚动数组)

Robot Problem Description Michael has a telecontrol robot. One day he put the robot on a loop with n cells. The cells are numbered from 1 to n clockwise. At first the robot is in cell 1. Then Michael uses a remote control to send m commands to the ro

HDU - 4576 Robot(概率dp+滚动数组)

题意:所有的格子围成一个圈,标号为1~n,若从格子1出发,每次指令告知行走的步数,但可能逆时针也可能顺时针走,概率都是1/2,那么问走了m次指令后位于格子l~r(1≤l≤r≤n)的概率. 分析: 1.因为m次指令后不知道会走到哪,会有很多种可能,但是知道从哪里出发,所以起始状态是已知的,在最初的状态,位于格子1是必然的,概率为1. 2.本题应用滚动数组,因为每次指令后都会延伸出无数种可能,这些可能是在前一种状态的基础上延伸的,而且延伸过后前一种状态的值不再有意义,完全可以被当前状态所覆盖. 3.

Hello 2019 D 素因子贡献法计算期望 + 概率dp + 滚动数组

https://codeforces.com/contest/1097/problem/D 题意 给你一个n和k,问n经过k次操作之后留下的n的期望,每次操作n随机变成一个n的因数 题解 概率dp计算出每个素因子留下的概率,乘以这个素因子的值就是这个素因子的贡献期望 定义\(dp[i][j]\)为第i次操作后剩下j个素因子的概率,概率dp顺着推 \(dp[i][j]->dp[i+1][k](k<=j)\) \(dp[i+1][k]+=dp[i][j]\frac{1}{j+1}(k<=j)

[poj3071]football概率dp

题意:n支队伍两两进行比赛,求最有可能获得冠军的队伍. 解题关键:概率dp,转移方程:$dp[i][j] +  = dp[i][j]*dp[i][k]*p[j][k]$表示第$i$回合$j$获胜的概率,原理为全概率公式. 如何判断相邻,通过位运算. 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdlib> 5 #include<cmath> 6

POJ3071(Football)--概率DP

题目在这 题意:有(1<<n个足球队进行比赛,在经过多轮一对一淘汰赛后决出冠军队伍,问最后哪支队伍能够获胜,即输出获胜概率最大的那支队伍编号.给了你n*n的矩阵,用来表示每支队伍间的各自胜率.输入-1为表示结束 en....网上当然也后不少解题报告,但是很多直接给出状态转移方程和贴出代码,而少了其中重要的推断过程,我觉得不是很好.所以自己给写一个较为详细的过程 首先呢,以n==3为例子,即8支队伍参赛.一种比赛情形是这样的 由图可知,在题中给定n后,需要比赛n轮即可知道冠军队伍是谁,我这里多了

poj3071之概率DP

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

HDU 1024 Max Sum Plus Plus --- dp+滚动数组

HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值,其中第i个子序列包括a[j], 则max(dp[m][k]),m<=k<=n 即为所求的结果 <2>初始状态: dp[i][0] = 0, dp[0][j] = 0; <3>状态转移: 决策:a[j]自己成为一个子段,还是接在前面一个子段的后面 方程: a[j]直接接在前面

poj3624 01背包入门 dp+滚动数组

poj3624 01背包 dp+滚动数组 Charm Bracelet Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25458   Accepted: 11455 Description Bessie has gone to the mall's jewelry store and spies a charm bracelet. Of course, she'd like to fill it with the bes

HDU 5617 Jam&#39;s maze dp+滚动数组

题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5617 bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=666&pid=1003 题解: 设dp[x1][x2][i]表示第i步时,从(1,1)点走到了(x1,y1),(n,n)点走到了(x2,y2)点的合法的总数. 1 #include<iostream> 2 #include