hdu 4089 Activation

概率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
*/


你可能感兴趣的:(hdu 4089 Activation)