POJ 3071:Football 概率DP

Football

题目链接:

http://poj.org/problem?id=3071

题意:

有2^n支足球队在比赛,实行淘汰制,规则如下:第一轮  1与2比,3与4比...  第二轮  1、2中的胜者和3、4中的胜者比... 以此类推 直到第n轮决出winner,求最终胜利的球队编号。

 

题解:

设dp[i][j]为在第i轮中j号球队胜利的概率  转移方程:dp[i][j]=∑(dp[i-1][w]*dp[i-1][j]*p[j][w])   w为该轮可能与j球队比赛的球队,则该轮j胜w的概率为上一轮j胜出的概率*上一轮w胜出的概率*j和w比赛j胜出的概率

             

代码

#include<stdio.h>
const int N=(1<<7)+1;
int id[N];
double dp[7][N],p[N][N],maxx;
int main()
{
  int n,res;
  while(~scanf("%d",&n)&&n!=-1)
  {
    for(int i=1;i<=1<<n;++i)
    {
      for(int j=1;j<=1<<n;++j)
      scanf("%lf",&p[i][j]);
      dp[0][i]=p[i][((i-1)^1)+1];
    }
    for(int i=1;i<n;++i)
    {
      for(int j=1;j<=1<<n;++j)
      id[j]=(j-1)/(1<<i);//把前i-1轮可能遭遇的队伍都统一编号
      for(int j=1;j<=1<<n;++j)
      {
        dp[i][j]=0.0;
        int v=1<<(i+1),w=j;
        for(int k=1;k<v;++k)
        {
          if((w+1)%v==1)w=w+1-v;
          else w++;
          if(id[w]!=id[j])//上一轮可能遇到的对手不可能是这一轮的对手
          dp[i][j]+=dp[i-1][j]*dp[i-1][w]*p[j][w];
        }
      }
    }
    maxx=-1.0;
    for(int i=1;i<=1<<n;++i)
    if(dp[n-1][i]>maxx)maxx=dp[n-1][i],res=i;
    printf("%d\n",res);
  }
}

  

posted @ 2016-06-12 21:10  kiuhghcsc  阅读(129)  评论(0编辑  收藏  举报