解题思路

动态规划
先读懂题目意思,是要问我们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;
}