牛客网多校第9场 E Music Game 【思维+数学期望】

题目:戳这里

题意:鼠标点击n下,第i次点击成功的概率为p[i],连续点击成功x次可以获得x^m分,求n次点击总分数的数学期望。

解题思路:数学期望的题很多都需要转化思维,求某一个单独状态对整体答案的贡献。这主要是利用了期望的可加性。

即:E(X+Y)=E(X)+E(Y);

比如在这题中,第2到3次连续点击成功,则意味着状态为0110....,后面的(...)所有情况概率和为1,也就是说影响第2到3次点击成功的因素只有前四次点击。

这样我们就可以预处理出所有段对答案的贡献,最后遍历一遍求和即可。

附ac代码:

 1 #include <cstdio>
 2 #include <cstdlib>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <cmath>
 7 #include <queue>
 8 #include <vector>
 9 #include <string>
10 #include <map>
11 #include <set>
12 using namespace std;
13 typedef long long ll;
14 const ll mod = 1e9 + 7;
15 const int maxn = 1e3 + 10;
16 ll p[maxn];
17 ll sc[maxn];
18 ll pre[maxn][maxn];
19 ll pmul(ll a, ll b)
20 {
21     ll res = 0;
22     while(b)
23     {
24         if(b&1)
25             res = (res + a) % mod;
26         b >>= 1;
27         a = (a + a) % mod;
28     }
29     return res;
30 }
31 ll pmod(ll a, ll b)
32 {
33     ll res = 1;
34     while(b)
35     {
36         if(b&1)
37             res = pmul(res, a) % mod;
38         b >>= 1;
39         a = pmul(a, a) % mod;
40     }
41     return res;
42 }
43 ll exgcd(ll a, ll b, ll &x, ll &y)
44 {
45     if(a == 0 && b == 0) return -1;
46     if(b == 0)
47     {
48         x = 1;y = 0;
49         return a;
50     }
51     ll d = exgcd(b, a % b, y, x);
52     y -= a/b*x;
53     return d;
54 }
55 ll mod_rev(ll a, ll n)
56 {
57     ll x, y;
58     ll d = exgcd(a, n, x, y);
59     if(d == 1) return (x % n + n) % n;
60     else return -1;
61 }
62 int main()
63 {
64     ll n, m;
65     ll inv = mod_rev(100ll, mod);
66   //  printf("%lld\n", inv);
67     scanf("%lld %lld", &n, &m);
68     for(ll i = 1; i <= n; ++i)
69     {
70         scanf("%lld", &p[i]);
71         sc[i] = pmod(i, m) % mod;
72       //  printf("%lld sc\n", sc[i]);
73     }
74     for(ll i = 1; i <= n; ++i)//预处理每一段的贡献
75     {
76         pre[i][i] = p[i] * inv % mod;
77         for(ll j = i + 1; j <= n; ++j)
78         {
79             pre[i][j] = pre[i][j - 1] * p[j] % mod * inv % mod;
80         }
81     }
82     ll ans = 0;
83     for(ll i = 0; i < n; ++i)//遍历求贡献和
84     {
85         for(ll j = i + 2; j <= n + 1; ++j)
86         {
87             ans += pre[i + 1][j - 1] * sc[j - i - 1] % mod * (100ll - p[i]) % mod * inv % mod * (100ll - p[j]) % mod  * inv % mod;
88             ans %= mod;
89         }
90     }
91     printf("%lld\n", ans % mod);
92 
93 }
View Code

 

posted @ 2018-08-17 14:22  euzmin  阅读(509)  评论(2编辑  收藏  举报