题目:戳这里
题意:鼠标点击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 ", 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 ", 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 ", ans % mod); 92 93 }