题目链接 https://ac.nowcoder.com/acm/contest/3003/C
题目就是有个模意义下的概率有点绕,其实没啥,把它当作分数的概率,每次注意 +mod 和 %mod就行了。
思路是dp,转移:dp[i][j]=dp[i-1][j](1-a[i])+dp[i-1][j-1]a[i]-----a[i]是概率,dp[i][j]是前i题对j题的概率。很容易看出来。
代码如下:

#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#include <set>

#define lson  rt << 1
#define rson  rt << 1 | 1
#define il inline
#define ll long long
#define LL long long
using namespace std;
const int maxn = 2000 + 10;
const ll inf = 0x7ffffffffff;
const ll mod = 1e9 + 7;

template<class T>
inline void read(T &res) {
    char c;
    T flag = 1;
    while ((c = getchar()) < '0' || c > '9')if (c == '-')flag = -1;
    res = c - '0';
    while ((c = getchar()) >= '0' && c <= '9')res = res * 10 + c - '0';
    res *= flag;
}

ll t;

ll qpow(ll a, ll b) {
    ll ans = 1;;
    a %= mod;
    while (b) {
        if (b & 1) ans = (ans * a) % mod;
        a = (a * a) % mod;
        b >>= 1;
    }
    return ans % mod;
}
ll a[maxn],dp[maxn][maxn];
int main() {
    ll n;
    cin>>n;
    for(ll i=1;i<=n;i++) read(a[i]);
    dp[1][0]=(1-a[1]+mod)%mod;
    dp[1][1]=(a[1]+mod)%mod;
//    cout<<dp[1][0]<<' '<<dp[1][1]<<endl;
    for(ll i=2;i<=n;i++){
        for(ll j=0;j<=i;j++){
            dp[i][j]=(dp[i-1][j]*(1-a[i]+mod)%mod+dp[i-1][j-1]*a[i]+mod)%mod;
        }
    }
    for(ll i=0;i<=n;i++){
        cout<<dp[n][i]<<' ';
    }
    return 0;
}