[POJ3071]Football(概率dp)

来源:互联网 发布:微信链接网络出错1003 编辑:程序博客网 时间:2024/04/29 06:41

题目描述

传送门
题意:
2^n个队进行足球赛,每个队打败另外一个队都有一个概率。
比赛一共进行n轮,每轮相邻的两只球队比赛,负者淘汰
问最后胜利的概率最大的是哪只球队

题解

概率dp
令f(i,j)表示第i轮第j支球队获胜的概率
那么f(i,j)=kf(i1,j)f(i1,k)p(j,k),其中k需要取遍这一轮所有有可能与j比赛的球队
感觉这题难不在dp,而在处理那棵二叉树啊。。。

代码

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#include<cmath>using namespace std;int n,champion,mi[10];double p[200][200],f[10][200],Max;void clear(){    champion=0;Max=0;    memset(f,0,sizeof(f));    memset(p,0,sizeof(p));}int main(){    while (~scanf("%d",&n))    {        if (n==-1) break;        clear();        mi[0]=1;for (int i=1;i<=n;++i) mi[i]=mi[i-1]*2;        for (int i=1;i<=mi[n];++i)            for (int j=1;j<=mi[n];++j)                scanf("%lf",&p[i][j]);        for (int i=1;i<=mi[n];++i) f[0][i]=1.0;        for (int i=1;i<=n;++i)            for (int j=1;j<=mi[n];++j)            {                int l=(j-1)/mi[i]*mi[i]+1,r=((j-1)/mi[i]+1)*mi[i];                if (j>(l+r)/2) r=(l+r)/2;                else l=(l+r)/2+1;                for (int k=l;k<=r;++k)                    f[i][j]+=f[i-1][k]*f[i-1][j]*p[j][k];            }        champion=1;Max=f[n][1];        for (int i=2;i<=mi[n];++i)            if (f[n][i]>Max)            {                Max=f[n][i];                champion=i;            }        printf("%d\n",champion);    }}
0 0
原创粉丝点击