The Moon
HDU 6558
分析
经典的概率dp题
dp[q][p]表示概率为p,q的期望
当q为1000时:
期望为Sn=p+2*p*(1-p)+3*p*(1-p)^2+------+n*p*(1-p)^(n-1)
Sn-(1-p)*Sn=2--------------------------->Sn=1/p
已知dp[q+20][p]和dp[q+15][p]求dp[q][p]
dp[q][p]与dp[q+20][p]相差一步,相当于q为初值为第一场,第一场期望为1*p*q;
q+20的第一场即为q的第二场,即dp[q+20][p]要加p+p*(1-p)+-----+p*(1-p)^(n-1)
由等比数列求值即为加1。
dp[q][p]与dp[q+15][p]相差一步,,dp[q+15][p]要加1
dp[q][p]=p*q+p*(1-q)*(dp[q+20][p]+1)+(1-p)*(dp[q+15][p]+1)
=p*q+p*(1-q)+(1-p)+p*(1-q)*dp[q+20][p]+(1-p)*dp[q+15][p]
=1+p*(1-q)*dp[q+20][p]+(1-p)*dp[q+15][p]
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
#pragma warning (disable:4996)
const int maxn = 1005;
long double dp[maxn][101];
long double dfs(int q, int p)
{
if (dp[q][p] > 0)return dp[q][p];
dp[q][p] = 1 + p / 100.0 * (1000 - q) / 1000 * dfs(min(q + 20, 1000), p) + (100.0 - p) * dfs(min(q + 15, 1000), p) / 100;
return dp[q][p];
}
int main() {
int n, p;
scanf("%d", &n);
for (int i = 1; i <= 100; i++)dp[1000][i] = 100.0 / i;
for (int k = 1; k <= n; k++) {
scanf("%d", &p);
printf("Case %d: %.10Lf\n", k, dfs(20, p));
}
}