Loading

DP Training I 简单概率DP

DP Training I 简单概率DP

题意

\(n\)次硬币,对于第\(i\)个硬币, 每次有\(p_i\)的概率正面。问\(n\)次后正面次数大于反面次数的概率

\[1 \leq n \leq 2999 \\ 0< p_i < 1 \]

分析

考虑每次计算概率都要在前面的基础上乘

直接设计状态\(dp[i][j]\)表示到现在有\(i\)个正面\(j\)个反面的概率

\[dp[i][j] += dp[i - 1][j] \times p[i]\\ dp[i][j] += dp[i][j - 1] \times (1 - p[i])\\ dp[0][0] = 1 \]

代码

double p[3005];
double dp[3005][3005];

int main(){
	int n = rd();
	for(int i = 1;i <= n;i++)
		scanf("%lf",&p[i]);
	dp[0][0] = 1.0;
	for(int i = 1;i <= n;i++){
		for(int j = 0;j <= i;j++){
			int x = j;
			int y = i - j;
			if(x) dp[x][y] += dp[x - 1][y] * p[i];
			if(y) dp[x][y] += dp[x][y - 1] * (1 - p[i]);
		}
	}
	double ans = 0;
	for(int i = 0;n - i > i;i++){
		ans += dp[n - i][i];
	}
	printf("%.10f",ans);
}
posted @ 2021-02-06 10:49  MQFLLY  阅读(92)  评论(0编辑  收藏  举报