题意:
比赛中有 道题。对于第 道题,你有 的概率自己解出来,有 的概率从左边队伍听到题解,有 的概率从右边的队伍听到题解。
问解出 道题的概率各是多少?
解法:
枚举
对于第 道题,最终能解出来的概率为 。
然后二进制枚举每道题是/否解出来,计算对应情况的概率,加到对应题数
复杂度为
dp
表示前 个问题,解出 个的概率。
初始化
转移方程为:
Code:
枚举
#include <bits/stdc++.h> using namespace std; double a[12], b[12], c[12], p[12], ans[13]; int main() { for(int i = 0; i < 12; i++) cin >> a[i]; for(int i = 0; i < 12; i++) cin >> b[i]; for(int i = 0; i < 12; i++) cin >> c[i]; for(int i = 0; i < 12; i++) p[i] = 1 - (1 - a[i]) * (1 - b[i]) * (1 - c[i]); for(int i = 0; i < 1 << 12; i++) { double tmp = 1.0; int k = 0; for(int j = 0; j < 12; j++) { if(i >> j & 1) k++, tmp *= p[j]; else tmp *= 1 - p[j]; } ans[k] += tmp; } cout << fixed << setprecision(6); for(int i = 0; i <= 12; i++) cout << ans[i] << endl; return 0; }
dp
#include <bits/stdc++.h> using namespace std; double a[13], b[13], c[13], p[13], dp[13][13]; int main() { for(int i = 1; i <= 12; i++) cin >> a[i]; for(int i = 1; i <= 12; i++) cin >> b[i]; for(int i = 1; i <= 12; i++) cin >> c[i]; for(int i = 1; i <= 12; i++) p[i] = 1 - (1 - a[i]) * (1 - b[i]) * (1 - c[i]); dp[0][0] = 1; for(int i = 1; i <= 12; i++) { dp[i][0] = dp[i - 1][0] * (1 - p[i]); for(int j = 1; j <= 12; j++) dp[i][j] = dp[i - 1][j] * (1 - p[i]) + dp[i - 1][j - 1] * p[i]; } cout << fixed << setprecision(6); for(int i = 0; i <= 12; i++) cout << dp[12][i] << endl; return 0; }