解题思路
动态规划
先读懂题目意思,是要问我们12到题里面,一共解决道题的概率分别是多少,不是解决当前这一题概率……
首先,求过这道题概率很麻烦……真的高中老师默默流下了欣慰的泪水。那不过这道题呢?很简单自己A不动,左边右边都没听到呗。
再用1减掉过不去的概率,留下的就是通过当前题目的概率)高中老师又留下了幸福的泪水。
那么就到了这个题目的重点了,这个可以递推?这个怎么样递推?
首先,如果我们知道了前i个题目的过题数,那么前i+1个题目过题数也可以推算到,后面要么过,要么不过。
所以从这个地方,找到dp切入点。 表示前i到题目过了j题,初始化
一直线性递推就是答案了。
#include <bits/stdc++.h> #pragma GCC optimize(2) #pragma GCC optimize(3) using namespace std; #define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0) typedef long long ll; const ll MOD = 1e9 + 7; inline ll read() { ll s = 0, w = 1; char ch = getchar(); while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); } while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar(); return s * w; } inline void write(ll x) { if (!x) { putchar('0'); return; } char F[200]; ll tmp = x > 0 ? x : -x; if (x < 0)putchar('-'); int cnt = 0; while (tmp > 0) { F[cnt++] = tmp % 10 + '0'; tmp /= 10; } while (cnt > 0)putchar(F[--cnt]); } inline ll gcd(ll x, ll y) { return y ? gcd(y, x % y) : x; } ll qpow(ll a, ll b) { ll ans = 1; while (b) { if (b & 1) ans *= a; b >>= 1; a *= a; } return ans; } ll qpow(ll a, ll b, ll mod) { ll ans = 1; while (b) { if (b & 1)(ans *= a) %= mod; b >>= 1; (a *= a) %= mod; }return ans % mod; } inline int lowbit(int x) { return x & (-x); } const int N = 15; double a[N], b[N], c[N]; double dp[N][N]; int main() { for (int i = 1; i <= 12; ++i) scanf("%lf", a + i); for (int i = 1; i <= 12; ++i) scanf("%lf", b + i); for (int i = 1; i <= 12; ++i) scanf("%lf", c + i); dp[0][0] = 1.0; for (int i = 1; i <= 12; ++i) { double no = (1.0 - a[i]) * (1.0 - b[i]) * (1.0 - c[i]); double ok = 1.0 - no; dp[i][0] = dp[i - 1][0] * no; for (int j = 1; j <= i; ++j) dp[i][j] = dp[i - 1][j - 1] * ok + dp[i - 1][j] * no; } for (int i = 0; i <= 12; ++i) printf("%.6f\n", dp[12][i]); return 0; }