UVA 12013 Entertainment 解题报告

题目

5.1 training 1

题意:

网球比赛:

一场比赛由5场轮换发球的sets组成,五局三胜制。

一场set由轮换发球的games组成,至少得6分且领先对方4分获胜。

一场game由同一个人发球的scores组成,至少得4分且领先对方2分获胜。

已知一个人自己发球和对方发球时赢得一个score的概率,且一开始由他先发球,求赢得比赛的概率。

题解:

比赛的时候想来想去,“领先对方X分获胜”的部分都只能想到暴力,DP递推和矩阵快速幂都用过,全T了。刷了一些概率DP后终于会做了,其实不难。

以计算赢得一场set为例,假设先后手赢得一场game的概率为m,y。

设ans为答案,dp[i][j]表示比分为i:j的概率,先用普通DP算出dp[0~i][0~j],则ans=dp[6][0~4]。

对于两人至少得5分的场合,设f[i]表示领先对方i分时要获胜的概率。

那么:

f[-1]=f[0]*y

f[0]=f[1]*m+f[-1]*(1-m)

f[1]=f[2]*y+f[0]*(1-y)

显然f[2]=1,所以可以求得f[i]具体的值,而到达f[0]的概率是dp[5][5],所以ans=ans+f[0]*dp[5][5]。(用f[1]或f[-1]也可以)

//Time:49ms
//Memory:0KB
//Length:1687B
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define MAXN 100010
#define INF 1000000007
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
#define EPS 1e-8
using namespace std;
double dp[10][10];
void cal2(double m,double y,int win)
{
    for(int i=0;i<=win;++i)
        for(int j=0;j<=win;++j)
            dp[i][j]=0;
    dp[0][0]=1;
//    for(int i=1;i<=win;++i)
//        dp[i][0]+=dp[i-1][0]*(i&1?m:y),
//        dp[0][i]+=dp[0][i-1]*(i&1?1-m:1-y);
    for(int i=0;i<=win;++i)
        for(int j=0;j<=win;++j)
        {
            if(i==win&&j<=win-2)  continue;
            if(j==win&&i<=win-2)  continue;
            dp[i+1][j]+=dp[i][j]*((i+j)&1?m:y);
            dp[i][j+1]+=dp[i][j]*((i+j)&1?1-m:1-y);
        }
    return ;
}
double cal(double m,double y,int tied)
{
    double ans=0,tmp;
    cal2(m,y,tied+1);
    for(int i=0;i<tied;++i) ans+=dp[tied+1][i];
    tmp=y*(1-y*(1-m))/(1-m-y+2*m*y);
    tmp*=m/(1-y*(1-m));
    ans+=dp[tied][tied]*tmp;
    return ans;
}
int main()
{
    //freopen("/home/moor/Code/input","r",stdin);
    int ncase;
    double m2,y2,m,y,m3,y3,ans;
    scanf("%d",&ncase);
    for(int hh=1;hh<=ncase;++hh)
    {
        scanf("%lf%lf",&m,&y);
        m/=100.0,y/=100.0;
        m2=cal(m,m,3);
        y2=cal(y,y,3);
        m3=cal(m2,y2,5);
        y3=cal(y2,m2,5);
        cal2(m3,y3,3);
        ans=0;
        for(int i=0;i<=2;++i)   ans+=dp[3][i];
        printf("Case #%d: %.4f%%\n",hh,ans*100);
    }
    return 0;
}


你可能感兴趣的:(UVA 12013 Entertainment 解题报告)