Football

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)=kf(i,j1)Pi kf(k,j1 ) The
explanation isiii teamadvances to jjIn round j, advance toj − 1 j-1 firstj1 round and beatj − 1 j-1jAll 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}\rceil2ji , 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}\rceil2ji⌉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+12ji+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-12ji1 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;
}

Guess you like

Origin blog.csdn.net/qq_43520313/article/details/108605955