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);
	  }
}
                    
                
                
            
        
浙公网安备 33010602011771号