题意
m 个游客, 他们都依次访问城市 1, 2, 3, ..., n , 第 i 个游客到达任意一个城市后有 p[i] 的概率会停下, 不再继续前行.
给定第 i 个人经过第 j 个城市的喜悦度 h[i][j] * (1 + 经过第 j 个城市的人数 / 经过第 j-1 个城市的人数) .
求每个人的喜悦度之和的期望.
m, n <= 16 .
分析
每个人的基本的喜悦度可以直接计算, 现在考虑人之间的影响.
枚举从第 i 个城市到第 i+1 个城市, 计算所有人的贡献
枚举经过第 i 个城市的人的状态
计算得到当前状态的概率 P , 所有经过的人的概率总和 S , 和人的个数 cnt .
枚举每个人 j , 考虑 j 的贡献.
贡献为 贡献的概率 * 期望的贡献次数 * H[j][i] .
贡献的概率为 P * p[i] .
期望的贡献次数为 (S - p[i] + 1) * cnt .
实现
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 #include <cctype> 5 #define F(i, a, b) for (register int i = (a); i <= (b); i++) 6 #define For(i, a, b) for (register int i = (a); i < (b); i++) 7 #define db double 8 inline int rd(void) { 9 int f = 1; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -1; 10 int x = 0; for (; isdigit(c); c = getchar()) x = x*10+c-‘0‘; return x*f; 11 } 12 13 const int N = 20; 14 15 int m, n, h[N][N], Tab[1000000]; 16 db p[N], Go[N][N], ans; 17 18 int main(void) { 19 #ifndef ONLINE_JUDGE 20 freopen("travel.in", "r", stdin); 21 #endif 22 23 m = rd(), n = rd(); 24 For(i, 0, m) Tab[1 << i] = i+1; 25 F(i, 1, m) { 26 scanf("%lf", p+i), Go[1][i] = 1; 27 F(j, 2, n) Go[j][i] = Go[j-1][i] * p[i]; 28 } 29 F(i, 1, m) F(j, 1, n) { 30 h[j][i] = rd(); 31 ans += Go[j][i] * h[j][i]; 32 } 33 34 For(j, 1, n) 35 For(s, 1, 1 << m) { 36 db Ps = 1, Sig = 0, sum = 0, cnt = 0; 37 F(i, 1, m) { 38 if (s >> i-1 & 1) 39 Ps *= Go[j][i], cnt++, Sig += p[i]; 40 else Ps *= 1-Go[j][i]; 41 } 42 for (int x = s; x > 0; x ^= (x & -x)) { 43 int i = Tab[x & -x]; 44 sum += p[i] * h[j+1][i] * (Sig - p[i] + 1); 45 } 46 ans += Ps * sum / cnt; 47 } 48 printf("%0.10lf\n", ans); 49 50 return 0; 51 }
时间: 2024-11-05 01:07:58