[POJ3071]Football(概率dp)

该博客介绍了如何使用概率动态规划解决POJ3071足球赛问题。博主阐述了比赛规则,指出每轮比赛两队对决,负者淘汰,总共有n轮。关键在于确定每轮中某队获胜的概率,即f(i,j) = ∑kf(i−1,j) * f(i−1,k) * p(j,k),难点在于处理涉及的二叉树结构。" 112484057,10294740,深入解析Rasa对话框架:训练过程详解,"['自然语言处理', '对话系统', '机器学习', 'Python框架', 'Rasa']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目描述

传送门
题意:
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);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值