概率dp,注意递推公式
#include <CSTDIO>
#include <STRING.H>
#include <MATH.H>
// hdu 4089
/*
dp[i][j]:有i个人排队,在第j位的概率
(1-p1)*dp[i][1] = p2*dp[i][i] + p4;
(1-p1)*dp[i][j] = p2*dp[i][j-1] + p3*dp[i-1][j-1] + p4; j<=k
(1-p1)*dp[i][j] = p2*dp[i][j-1] + p3*dp[i-1][j-1]; j>k
化简:
_p2 = p2/(1-p1);
_p3 = p3/(1-p1);
_p4 = p4/(1-p1);
设dp[i][j] = b[j] = p2*b[j-1] + c[j];
b[j-1] = p2*b[j-2] + c[j-1];
...
b[2] = p2*b[1] + c[2];
b[1] = p2*b[i] + c[1];
因此
b[i] = (c[i] + p2*c[i-1] + p2^2*c[i-2] + ... + p2^(n-1)*c[1])/(1-p2^n);
*/
const int MAXN = 2010;
const double _inf = 1e-10;
double p1, p2, p3, p4, _p1, _p2, _p3, _p4;
double dp[MAXN][MAXN];
int n, m, k;
double c[MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int i, j;
while (scanf("%d%d", &n, &m) != EOF)
{
scanf("%d%lf%lf%lf%lf", &k, &p1, &p2, &p3, &p4);
if (p4 < _inf)
{
printf("0.00000\n");
continue;
}
_p2 = p2/(1-p1);
_p3 = p3/(1-p1);
_p4 = p4/(1-p1);
dp[1][1] = p4/(1-p1-p2);
for (i = 2; i<= n; ++i)
{
for (j = 2; j<= i; ++j)
{
c[j] = _p3 * dp[i-1][j-1];
if (j <= k) c[j] += _p4;
}
c[1] = _p4;
double res = 1.0;
double sum = 0.0;
for (j = i; j >= 1; --j)
sum += res*c[j], res *= _p2;
dp[i][i] = sum/(1.0-res);
dp[i][1] = _p2 * dp[i][i] + c[1];
for (j = 2; j< i; ++j)
dp[i][j] = _p2 * dp[i][j-1] + c[j];
}
printf("%.5lf\n", dp[n][m]);
}
return 0;
}
/*
0.30427
0.23280
0.90343
*/