博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
poj 3071 Football(线段树+概率)
阅读量:4361 次
发布时间:2019-06-07

本文共 3698 字,大约阅读时间需要 12 分钟。

Football
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2801   Accepted: 1428

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

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.

 
 
每一个节点记录这个区间每一个队赢的概率。

 
 
#include 
#include
using namespace std;const int maxn = 200;const double eps = 0.0001;struct tree{ int l , r; double win[maxn];}a[4*maxn];double P[maxn][maxn];int N[10] = {1 , 2 , 4 , 8 , 16 , 32 , 64 , 128 , 256 , 512};int n;void initial(){ for(int i = 0; i < 4*maxn; i++){ for(int j = 0; j < maxn; j++){ a[i].win[j] = 0.0; } }}void build(int l , int r , int k){ a[k].l = l; a[k].r = r; if(l == r){ a[k].win[l] = 1.0; }else{ int mid = (l+r)/2; build(l , mid , 2*k); build(mid+1 , r , 2*k+1); int i = l; while(i <= mid){ for(int j = mid+1; j <= r; j++){ a[k].win[i] += a[2*k].win[i]*a[2*k+1].win[j]*P[i][j]; } i++; } while(i <= r){ for(int j = l; j <= mid; j++){ a[k].win[i] += a[2*k].win[j]*a[2*k+1].win[i]*P[i][j]; } i++; } }}void readcase(){ for(int i = 0; i < N[n]; i++){ for(int j = 0; j < N[n]; j++){ scanf("%lf" , &P[i][j]); } }}void computing(){ build(0 , N[n]-1 , 1); int ans = 0; for(int i = 1; i < N[n]; i++){ if(a[1].win[i] - a[1].win[ans] > eps){ ans = i; } } printf("%d\n" , ans+1);}int main(){ while(scanf("%d" , &n) && n != -1){ initial(); readcase(); computing(); } return 0;}

转载于:https://www.cnblogs.com/llguanli/p/7151021.html

你可能感兴趣的文章
Thread
查看>>
char * 与char []探究理解
查看>>
QT窗体显示在屏幕中间位置
查看>>
emmet使用技巧
查看>>
RPC-Thrift(二)
查看>>
MSSQL for Linux 安装指南
查看>>
【Golang 接口自动化08】使用标准库httptest完成HTTP请求的Mock测试
查看>>
前端必读:浏览器内部工作原理
查看>>
Uri、URL和URN三者的区别
查看>>
数据字典的转换
查看>>
关于动态添加iview admin路由以及刷新侧边栏
查看>>
ApplicationInsights的探测器尝鲜
查看>>
java 解析Json格式数据
查看>>
unix中的线程池技术详解
查看>>
CSS简介
查看>>
常用三大软件评价1
查看>>
MVC各层介绍使用---初步理解
查看>>
单例对象的创建与销毁
查看>>
知识点关键词(记录一下)
查看>>
国际结算业务
查看>>