[简单DP] COJ 1123 PK武林盟主

状态转移方程p[i,j] = 0.5*(p[i-1,j]+p[i,j-1])。

浮点数运算,初始时要向上取整。

# include <stdio.h>
# include <math.h>
# include <string.h>

int ap1, ap2, hp1, hp2;

double f[1005][1005];

double cal(int x, int y)
{
    if (f[x][y] >= 0) return f[x][y];
    if (x <= 0) return f[x][y] = 0;
    if (y <= 0) return f[x][y] = 100;
    return f[x][y] = 0.5*(cal(x, y-1)+cal(x-1, y));
}

int main()
{
    int n, i, j, m;
    while (~scanf("%d%d%d%d", &hp1, &hp2, &ap1, &ap2))
    {
        n = (int)ceil(1.0*hp1/ap2), m = (int)ceil(1.0*hp2/ap1);
        for (i = 0; i <= n; ++i)
        for (j = 0; j <= m; ++j)
            f[i][j] = -1;
        printf("%.4f\n", cal(n, m));
    }
    
    return 0;
}

在HDOJ上是RE的(ACCESS_VOALATION),原因是确实下标引用出界了(这里没有限制比率范围,只能用组合的方法来做):

假设经过x次胜出,则x<n+m,且x>=n,于是有p = 0.5^n*C(n,n)+0.5^(n+1)*C(n+1,n)+...+0.5^(n+m-1)*C(n+m-1,n),后项项可以通过前项迭代得到,浮点运算,可以先取对数。

原文地址:https://www.cnblogs.com/JMDWQ/p/2626878.html