Description
淘汰賽制是一種極其殘酷的比賽制度。2n名選手分別標號1,2,3,……2n-1,2n,他們將要參加n輪的激烈角逐。每一輪中,將所有參加該輪的選手按標號從小到大排序後,第1位與第2位比賽,第3位與第4位比賽,第5位與第6位比賽……只有每場比賽的勝者纔有機會參加下一輪的比賽(不會有平局)。這樣,每輪將淘汰一半的選手。n輪過後,只剩下一名選手,該選手即爲最終的冠軍。
現在已知每位選手分別與其他選手比賽獲勝的概率,請你預測一下誰奪冠的概率最大。
Input
輸入文件第一行是一個整數n(1<=n<=10),表示總輪數。接下來2n行,每行2n個整數,第i行第j個是pij(0<=pij<=100,pii=0,pij+pji=100),表示第i號選手與第j號選手比賽獲勝的概率。
Output
輸出文件只有一個整數c,表示奪冠概率最大的選手編號(若有多位選手,輸出編號最小者)。
Sample Input
2
0 90 50 50
10 0 10 10
50 90 0 50
50 90 50 0
Sample Output
1
Data Constraint
Hint
【數據規模】
30%的數據滿足n<=3
100%的數據滿足n<=10
//written by zzy
題目大意:
給你個矩陣,a[i][j]表第i人和第j人比賽的勝率,按淘汰賽制,求第幾人勝率最大。
題解:
考慮dp,設f[i][j]表到第i輪j獲勝的概率,易推
f[i][j]=f[i-1][j]×sum(f[k][j]×a[j][k])其中k爲第i輪j要比賽的人
考慮k的範圍
用num(i)=(x-1)/2i-1+1表第i輪x的組數
num的變化如下圖所示
x1,x2,…xn
i=0 |1 2 3 4 5 6 7 8
i=1 |1 1 2 2 3 3 4 4
i=2 |1 1 1 1 2 2 2 2
顯然,若第i輪num(x)爲奇數,x要跟num爲num(x)+1的人比賽
若第i輪num(x)爲偶數,x要跟num爲num(x)-1的人比賽
#include<bits/stdc++.h>
#define N 1<<11
using namespace std;
int i,j,k,n,m,d,numj,numk,ans;
int a[N][N];
double f[N][N],s,Max;
int num(int x)
{
return (x-1)/d+1;
}
int main()
{
scanf("%d",&n);
for (i=1;i<=1<<n;i++)
for (j=1;j<=1<<n;j++)
scanf("%d",&a[i][j]);
for (j=1;j<=1<<n;j++) f[0][j]=1;
d=1;
for (i=1;i<=n;i++)
{
for (j=1;j<=1<<n;j++)
{
s=0;
f[i][j]=f[i-1][j];
numj=num(j);
if (numj&1) numk=numj+1;
else numk=numj-1;
for (k=1;k<=1<<n;k++)
if (num(k)==numk)//求第i輪和j比賽的人
s+=f[i-1][k]*a[j][k]/100;
f[i][j]*=s;
}
d*=2;
}
for (i=1;i<=1<<n;i++)
if (f[n][i]>Max)
{
Max=f[n][i]; ans=i;
}
printf("%d",ans);
}