//dp[i][j]表示做前i道题做对j道 //考虑状态转移方程,如果前i-1道题做对j道,那么第i道题肯定是做错了,如果前i-1道题做对了j-1道题,那么第i道题肯定是做对了(这样就可以得出状态转移方程) /*状态转移方程为: dp[i][j]= dp[i-1][j]*(1-p[i]+mod)%mod ------第i道题做错了的情况 + dp[i-1][j-1]*p[i]%mod ------第i道题做对了的情况 */ #include <cstdio> #include <cstring> #include <string> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <sstream> #include <map> #include <set> #include <queue> #include <stdlib.h> typedef long long ll; using namespace std; const int maxn=2020; const int mod=1e9+7; #define ll long long ll p[maxn]; ll dp[maxn][maxn]; int main() { int n; //一共有n道题 cin >> n; for(int i=1;i<=n;i++) //每一道题正确的概率 { cin >> p[i]; } dp[0][0]=1; //前0道题正确0道的概率是百分之百 for(int i=1;i<=n;i++) { //因为前i道题做对0道的j不能减为0,所以要单独写出来 dp[i][0]=dp[i-1][0]*(mod+1-p[i])%mod; //前i道题做对0道的概率是前i-1道题做对0道的概率*当前这道题没有做对的概率 for(int j=1;j<=i;j++) { dp[i][j]= (dp[i-1][j]*(mod+1-p[i])%mod + dp[i-1][j-1]*(p[i]))%mod; } } for(int i=0;i<=n;i++) { cout << dp[n][i]; if(i!=n) cout << " "; } cout << endl; return 0; }