状态转移方程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),后项项可以通过前项迭代得到,浮点运算,可以先取对数。