题解|#算概率#
这是一个经典的概率动态规划(DP)问题。我们可以将其看作是计算二项分布的变体(因为每道题的概率 不同,这实际上是泊松二项分布)。
核心思路
我们需要计算做对 到
道题的概率。
假设
表示当前已经考虑过的题目中,恰好做对
题的概率。
当我们引入第 道题(做对概率为
,做错概率为
)时,对于每一个可能的做对数量
,有两种情况可以达到状态
:
- 前
题中已经做对了
题,并且第
题做错了。
- 概率贡献:
- 概率贡献:
- 前
题中只做对了
题,并且第
题做对了。
- 概率贡献:
- 概率贡献:
状态转移方程
所有的运算都需要在模 下进行。
代码实现
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr static ll MOD = 1e9 + 7;
void solve() {
int n;
cin >> n;
vector<ll> p(n);
for (int i = 0; i < n; i++) {
cin >> p[i];
}
vector<ll> dp(n + 1, 0);
dp[0] = 1;
for (int i = 1; i <= n; i++) {
ll not_p = (MOD + 1 - p[i - 1]) % MOD;
for (int j = i; j >= 0; j--) {
dp[j] = ((j > 0 ? dp[j - 1] : 0) * p[i - 1] + dp[j] * not_p) % MOD;
}
}
for (int i = 0; i <= n; i++) {
cout << dp[i];
cout << (i == n ? "\n" : " ");
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
while (T--) {
solve();
}
return 0;
}
#从夯到拉,评价编程语言#算法编程训练 文章被收录于专栏
各类牛客算法编程训练联赛、集训营
查看12道真题和解析


阿里云成长空间 763人发布