思路

  用 f(i,j) 来表示当前做了i道题,共做对了j道题

  状态 f[i][j] = f[i-1][j] * (1-p[i]) + f[i-1][j-1] * p[i]

  第一种:由于i-1时对了j题,所以第i题做错了;

  第二种:由于i-1时对了j-1题,所以第i题对了;

  时间复杂度O(n^2)

 

CODE

 

 1 #include <bits/stdc++.h>
 2 #define dbg(x) cout << #x << "=" << x << endl
 3 
 4 using namespace std;
 5 typedef long long LL;
 6 
 7 template<class T>inline void read(T &res)
 8 {
 9     char c;T flag=1;
10     while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0';
11     while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag;
12 }
13 
14 namespace _buff {
15     const size_t BUFF = 1 << 19;
16     char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
17     char getc() {
18         if (ib == ie) {
19             ib = ibuf;
20             ie = ibuf + fread(ibuf, 1, BUFF, stdin);
21         }
22         return ib == ie ? -1 : *ib++;
23     }
24 }
25 
26 int qread() {
27     using namespace _buff;
28     int ret = 0;
29     bool pos = true;
30     char c = getc();
31     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
32         assert(~c);
33     }
34     if (c == '-') {
35         pos = false;
36         c = getc();
37     }
38     for (; c >= '0' && c <= '9'; c = getc()) {
39         ret = (ret << 3) + (ret << 1) + (c ^ 48);
40     }
41     return pos ? ret : -ret;
42 }
43 
44 const int kmaxn = 1007;
45 LL f[kmaxn][kmaxn];
46 const LL mod = 1e9 + 7;
47 int n;
48 LL p[kmaxn];
49 
50 int main()
51 {
52     scanf("%d",&n);
53     for(int i = 1; i <= n; ++i) {
54         scanf("%lld",&p[i]);
55     }
56     f[0][0] = 1;
57     for(int i = 1; i <= n; ++i) {
58         f[i][0] = f[i-1][0] * (mod+1-p[i]) % mod;
59         for(int j = 1; j <= n; ++j) {
60             f[i][j] = ((f[i-1][j]*(i-p[i]+mod)) % mod + f[i-1][j-1]*(mod+p[i]) % mod)% mod;
61         }
62     }
63     for(int i = 0; i < n; ++i) {
64         printf("%lld ",f[n][i]);
65     }
66     printf("%lld\n",f[n][n]);
67     return 0;
68 }
View Code