淘汰赛制_NOI导刊2010提高(01)

题目描述

淘汰赛制是一种极其残酷的比赛制度。2n名选手分别标号1,2,3,…,2^n-1,2^n,他们将要参加n轮的激烈角逐。每一轮中,将所有参加该轮的选手按标号从小到大排序后,第1位与第2位比赛,第3位与第4位比赛,第5位与第6位比赛……只有每场比赛的胜者才有机会参加下一轮的比赛(不会有平局)。这样,每轮将淘汰一半的选手。n轮过后,只剩下一名选手,该选手即为最终的冠军。

现在已知每位选手分别与其他选手比赛获胜的概率,请你预测一下谁夺冠的概率最大。

输入格式

输入文件elimination.in。第一行是一个整数n(l≤n≤l0),表示总轮数。接下来2^n行,每行2^n个整数,第i行第j个是Pij(0≤pij≤100,Pii=0,Pij+Pji=100),表示第i号选手与第j号选手比赛获胜的概率。

输出格式

输出文件elimination.out。只有一个整数c,表示夺冠概率最大的选手编号(若有多位选手,输出编号最小者)。

输入输出样例

输入 #1
  2
  0 90 50 50
  10 0 10 10
  50 90 0 50
  50 90 50 0
输出 #1
 1

说明/提示

30%的数据满足n≤3;100%的数据满足n≤10。

_NOI导刊2010提高(01)

分析:

一道较为有思考难度的DP,通过考虑每次原位置的变化进行DP即可。

CODE:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cmath>
 5 #include<cstring>
 6 using namespace std;
 7 const int M=2005;
 8 const double esp=0.000001;
 9 const double hyh=0.999;
10 double f[M][15];
11 int win[M][M];
12 int n;
13 int get(){
14     char c=getchar();
15     int res=0,f=1;
16     while (c>'9'||c<'0'){
17         if (c=='-') f=-1;
18         c=getchar();
19     }
20     while (c<='9'&&c>='0'){
21         res=(res<<3)+(res<<1)+c-'0';
22         c=getchar();
23     }
24     return res*f;
25 }
26 double maxn;
27 int pos;
28 int main(){
29     n=get();
30     long long m=(1<<n);
31     for (int i=1;i<=m;i++)
32         for (int j=1;j<=m;j++)
33         win[i][j]=get();
34     for (int i=1;i<=m;i++) f[i][0]=1;
35     for (int i=1;i<=n;i++){
36         for (int j=1;j<=m;j++){
37             int posi=(int)(j*1.0/(1<<(i-1))+hyh);
38             //int posi=ceil((double)j/(1<<(i-1)));
39             int posx=(posi&1)?posi+1:posi-1;
40             for (int k=posx*(1<<(i-1))-(1<<(i-1))+1;k<=posx*(1<<(i-1));k++)
41                 f[j][i]+=f[j][i-1]*win[j][k]/100*f[k][i-1];
42             //cout<<f[j][i]<<endl;
43         }
44     }
45     for (int i=1;i<=m;i++){
46         if (f[i][n]>maxn+esp) maxn=f[i][n],pos=i;
47         //cout<<f[i][n]<<endl;
48     }
49     cout<<pos<<endl;
50     return 0;
51 }

猜你喜欢

转载自www.cnblogs.com/kanchuang/p/11644632.html
今日推荐