题目:
分析:
定义一个数组dp[i][j]表示前i道题做对了j道题,分以下两种情况:
- 当j>0时,此时前i道题最对j道题用两种情形,一是前i-1道题就做对了j道题,此时第i道题就是做错,二是前i-1道题做对了j-1道题,此时第i道题就是做对,公式如下:
dp[i][j] = dp[i-1][j] x (mod +1 - p[i]) % mod + dp[i-1][j-1] x p[i]%mod - 当j=0时,此时只有一种情况,即前i-1到题都做错了,并且第i道题也做错 此时公式如下:
dp[i][0] = dp[i-1][0] x (mod + 1 - p[i] )%mod
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
using namespace std;
const int MAXN = 2005;
const int MOD = 1e9 + 7;
ll p[MAXN],dp[MAXN][MAXN]; //dp[i][j]表示前i道题做对j道题的概率
int n;
int main()
{
scanf("%d",&n);
dp[0][0] = 1;
for(int i=1;i<=n;++i)
scanf("%lld",&p[i]);
for(int i=1;i<=n;++i)
{
dp[i][0] = dp[i-1][0] * (MOD+1-p[i]) % MOD;
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)
printf("%lld ",dp[n][i]%MOD);
printf("\n");
return 0;
}