淘汰赛制

49 篇文章 0 订阅
35 篇文章 0 订阅
 淘汰赛制

【问题描述】

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

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

【输入文件】

输入文件。第一行是一个整数,表示总轮数。接下来行,每行个整数,第行第个是,表示第号选手与第号选手比赛获胜的概率。

【输出文件】

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

【样例输入】

【样例输出】

【数据规模】

的数据满足的数据满足

 

思路:

    d[i,j]表示第j位选手通过第i轮的概率;P[i,j]表示第i号选手与第j号选手比赛获胜的概率;

   状态转移方程:d[i,j] =d [i-l,j]*sum{d[i-l,k]*p[j,k]}i=l..nj=1..2nk为所有可能在第i轮与第j位选手交战的选手编号),边界条件d[0,j]=1。时间复杂度O(n2*2n)

方程其实还好理解,就是一开始没有想到怎么去求k,看了一位大牛的解题报告后想明白了。

第i轮其实就是每2^i个人中选出一个,而这些人的编号又是相连的,且最小可能编号为(j-1) div (1 shl i)*(1 shl i)+1,因为有边界,要确保都是从上一组2^i+1个人开始的,所以是j-1,还有分左右子树来分析,可能分析得有点乱,画个图区看看就清楚了。下面就是我的ac代码,注释里的是调试输出和那位大牛的写法。

ac程序:

var a:array[0..1024,0..1024] of longint;
f:array[0..10,0..1024] of real;
n,m,i,j,k,x:longint;
sum:real;
begin
 assign(input,'elimination.in'); assign(output,'elimination.out');
 reset(input); rewrite(output);
 readln(n);
 m:=1 shl n;
 for i:=1 to m do
  f[0,i]:=1;
 for i:=1 to m do
  begin for j:=1 to m do
   read(a[i,j]);
  readln; end;
 for i:=1 to n do
  for j:=1 to m do
   begin
    x:=j-1;
    x:=(x div (1 shl i)) * (1 shl i); {writeln(x,' X','j:',j);}
    {x:=j;}
    {repeat
    dec(x);
    until x mod (1 shl i)=0;   writeln(x); }
    if x+1 shl (i-1)>=j then inc(x,1 shl (i-1));
    for k:=x+1 to x+1 shl (i-1) do
     f[i,j]:=f[i,j]+f[i-1,k]*a[j,k]/100;
    f[i,j]:=f[i,j]*f[i-1,j];
   end;
 {for i:=1 to m do
  writeln(f[n,i]);}
 sum:=0;
 for i:=1 to m do
  if f[n,i]>sum then
   begin sum:=f[n,i]; x:=i; end;
 writeln(x);
 close(input); close(output);
end.


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值