Subject:
https://ac.nowcoder.com/acm/problem/107668
Gives you 2 n 2^n2n teams, adjacent teams play in each round. Tell youiii team beatjjThe probability of team j isP ij P_{ij}Pij, Ask which team has the greatest chance of winning!
Idea:
Let f (i, j) f(i,j)f(i,j ) means teamiii can advance tojjProbability of round j , initially0 00轮,f (i, 0) = 1 f (i, 0) = 1f(i,0)=1 , and then for all possiblejjround j and teamiii match teamkkk, 有
f (i, j) = ∑ kf (i, j - 1) ∗ P ik ∗ f (k, j - 1) f (i, j) = \ sum_ {k} f (i, j-1 ) * P_ {ik} * f (k, j-1)f(i,j)=k∑f(i,j−1)∗Pi k∗f(k,j−1 ) The
explanation isiii teamadvances to jjIn round j, advance toj − 1 j-1 firstj−1 round and beatj − 1 j-1j−All possible opponents in 1 round.
In addition, we can determine the number of team i in round j, for example
,0 00 rounds1, 2, 3, 4, 5, 6, 7, 8 1, 2, 3, 4, 5, 6, 7, 81 , 2 , 3 , 4 , 5 , 6 , 7 , 8
No.1 11 round1, 3, 5, 7 1, 3, 5, 71 , 3 , 5 , 7
of222 rounds3, 5 3, 53 , 5
,3, 33 rounds5 55
Observe5 55 , will find the teamiii is injjThe position of wheel j is⌈ i 2 j ⌉ \lceil\frac{i}{2^j}\rceil⌈2ji⌉ , equivalent tojjj round with2 j 2^j2j is a group, each group wins one person, theniii is the first⌈ i 2 j ⌉ \lceil\frac{i}{2^j}\rceil⌈2ji⌉Group .
- 如果 ⌈ i 2 j ⌉ \lceil\frac{i}{2^j}\rceil ⌈2ji⌉ is odd, then sum⌈ i 2 j ⌉ + 1 \lceil\frac{i}{2^j}\rceil+1⌈2ji⌉+1 group play.
- 如果 ⌈ i 2 j ⌉ \lceil\frac{i}{2^j}\rceil ⌈2ji⌉ is even, then sum⌈ i 2 j ⌉ − 1 \lceil\frac{i}{2^j}\rceil-1⌈2ji⌉−1 group play.
#include<stdio.h>
#include<cstring>
using namespace std;
const int N=8;
const int eps=1e-6;
double a[1<<N][1<<N],f[1<<N][N],maxi;
int n,locate;
double dfs(int x,int y)
{
if(f[x][y])
return f[x][y];
f[x][y]=0;
int tu=x%(1<<(y-1))?x/(1<<(y-1))+1:x/(1<<(y-1));//x为第几个
tu=tu%2?tu+1:tu-1;//x和哪组打
for(int i=1; i<=1<<n; i++)//枚举可能的对手
{
int tu1=i%(1<<(y-1))?i/(1<<(y-1))+1:i/(1<<(y-1));
if(tu1==tu)
f[x][y]+=a[x][i]*dfs(i,y-1);
}
f[x][y]*=dfs(x,y-1);
return f[x][y];
}
int main()
{
while(scanf("%d",&n)==1&&n!=-1)
{
for(int i=1; i<=1<<n; i++)
for(int j=1; j<=1<<n; j++)
scanf("%lf",&a[i][j]);
for(int i=1; i<=1<<n; i++)
f[i][0]=1.0;
for(int i=1; i<=1<<n; i++)
{
double res=dfs(i,n);
if(res-maxi>eps)
maxi=res,locate=i;
}
printf("%d\n",locate);
}
return 0;
}