jzoj 1342. 淘汰賽制 (Standard IO)&&洛谷1769

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章