标签:期望 i++ 概率dp 代码 size code memset ++ 计算
有\(N\)个数,依次选取,第\(i\)个数被选择的概率为\(p_i\),求至少选了\(L\)次后所选取的数的和\(+K\geq 0\)的概率。
设\(f_{i,j,k}\)为选到第\(i\)个数时已经选了\(j\)个,当前和为\(k\)时的概率。
考虑当前和\(\geq N\)时,可以将它视作为\(N\),因为它们都一定满足了选完之后\(\geq 0\)的条件,所以把它们归到\(N\)中,一起计算选不选择的概率即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
int n, l, K;
int w[201];
double ans;
double p[201], f[2][201][401];
int main() {
scanf("%d %d %d", &n, &l, &K);
for (int i = 1; i <= n; i++)
scanf("%lf", &p[i]), p[i] /= 100;
for (int i = 1; i <= n; i++)
scanf("%d", &w[i]);
if (K > n)
K = n;
f[0][0][K + 200] = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++)
for (int k = -i; k <= n; k++) {
f[(i + 1) & 1][j + 1][std::min(k + w[i + 1], n) + 200] += f[i & 1][j][k + 200] * p[i + 1];
f[(i + 1) & 1][j][k + 200] += f[i & 1][j][k + 200] * (1 - p[i + 1]);
}
memset(f[i & 1], 0, sizeof(f[i & 1]));
}
for (int i = l; i <= n; i++)
for (int j = 0; j <= n; j++)
ans += f[n & 1][i][j + 200];
printf("%.6lf", ans);
}
标签:期望 i++ 概率dp 代码 size code memset ++ 计算
原文地址:https://www.cnblogs.com/HSZGB/p/14586161.html