9.29 - 10.6 更新时间约持续一周
一、数学期望
概念:简单地说,随机变量 X 的数学期望 E(X) 就是所有可能的值按照概率加权的和。
求解方法:按照定义求解。
- 计算出所有可能的值
- 计算出对应的概率
- 求出可能的加权和
求解工具
- 期望的线性性质:有限个随机变量之和的数学期望等于每个随机变量的数学期望之和。例如,对于两个随机变量 X 和 Y,E(X + Y) = E(X) + E(Y)。
- 全期望公式:类似于全概率公式,把所有情况不重复、不遗漏地分成若干类,每类计算数学期望,然后把这些数学期望按照每类地概率加权求和。
二、Practice
过河 Crossing Rivers
过河的最小时间 ,最大时间 ,由于过河的时间是连续的,所以过河时间的期望 (船正好在岸边时间最小,船刚走时间最大)。
最终的答案就是,陆地距离 + 过河期望时间。
#include <bits/stdc++.h>
using namespace std;
int n, D, p, L, v;
double ans;
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int main() {
int t = 0;
while (1) {
n = read(), D = read();
if (!n && !D) break;
ans = 1.0 * D;
while (n--) {
p = read(), L = read(), v = read();
ans += 2.0 * L / v - L;
}
printf("Case %d: %.3lf\n\n", ++t, ans);
}
return 0;
}
优惠券 Coupons
题目链接:优惠券 Coupons
假设我们某个情况下,我们已经有了 k 种图案,在这个条件下,获得一个新图案需要 天,那我们要求的就是 。由于已经有了 k 种图案,那么获得一个新图案的概率就是 ,那么期望天数 ,最终答案就是
要注意一下分数时候的输出格式。
另外就是这道题我刚开始给卡常了,有点ex。
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n, x, y;
int gcd(int a, int b) { return a == 0 ? b : gcd(b % a, a); }
signed main() {
while (scanf("%lld", &n) != EOF) {
x = n, y = 1;
for (int i = 2; i <= n; i++) {
x = x * i + y * n, y *= i;
int GCD = gcd(x, y);
x /= GCD, y /= GCD;
}
if (x % y == 0) printf("%lld\n", x / y);
else {
int a = x / y;
x %= y;
int lena = log10(a) + 1, leny = log10(y) + 1;
for (int i = 0; i <= lena; i++) printf(" ");
printf("%lld\n%lld ", x, a);
for (int i = 1; i <= leny; i++) printf("-");
puts("");
for (int i = 0; i <= lena; i++) printf(" ");
printf("%lld\n", y);
}
}
return 0;
}
P1654 OSU!
题目链接:P1654 OSU! - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
设 位前 i 位的期望分数, 表示前 i 位末尾的连续的 1 的期望长度。可以得到
所以
第 i 位为 1 的概率为 ,所以
即
所以除了 以外,还需要记录前 i 位末尾的连续的 1 的期望长度的平方 。
,所以
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
double f[N], x[N], y[N], d;
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%lf", &d);
x[i] = (x[i - 1] + 1) * d;
y[i] = (y[i - 1] + 2 * x[i - 1] + 1) * d;
f[i] = f[i - 1] + (3 * y[i - 1] + 3 * x[i - 1] + 1) * d;
}
printf("%.1lf", f[n]);
return 0;
}
Sugar Sweet II
题目链接:2023ICPC区域赛杭州站H题
- 当 的时候,无论 a[b[i]] 是否更新,即无论事件以什么顺序发生,a[i] 一定会被更新,则第 i 个孩子手上的糖的期望为 a[i] + w[i]。
- 当 的时候,无论 a[b[i]] 是否更新,即无论事件以什么顺序发生,a[i] 一定无法更新,则第 i 个孩子手上的糖的期望为 a[i]。
- 除去以上两种情况,a[i] 是否更新取决于 a[b[i]] 是否更新。对于这种情况,我们可以以 (b[i], i) 建一张有向图,记录一个 dis 表示该节点更新前有多少个节点需要更新,第一种情况的 dis 记为 1,第二种情况的 dis 记为 0,通过 dfs 遍历得到每一个节点的 dis。每一个节点可以更新的概率就是 ,因为只需要这 dis 个节点以这一种特定顺序排列就可以保证该节点被更新。期望就是 ,最后要求乘法逆元。
- 对于 即 的乘法逆元,根据费马小定理,当 a 和 p 互质的时候,有 ,则 即 。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 5e5 + 10, mod = 1e9 + 7;
int a[N], b[N], w[N], fac[N], dis[N], head[N], num = 0;
struct edge { int to, nxt; } e[N];
inline int read() {
int x = 0, f = 1; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
void addEdge(int u, int v) { e[++num] = (edge){v, head[u]}, head[u] = num; }
int qpow(int x, int k) {
int res = 1LL;
while (k) {
if (k & 1) res = res * x % mod;
x = x * x % mod;
k >>= 1;
}
return res;
}
void dfs(int u) {
for (int i = head[u], v; i; i = e[i].nxt) {
v = e[i].to;
dis[v] = dis[u] + 1;
dfs(v);
}
}
signed main() {
fac[0] = 1;
for (int i = 1; i < N; i++) fac[i] = fac[i - 1] * i % mod;
int t = read();
while (t--) {
int n = read();
for (int i = 1; i <= num; i++) e[i] = {0, 0};
num = 0;
for (int i = 1; i <= n; i++) a[i] = read(), dis[i] = 0;
for (int i = 1; i <= n; i++) b[i] = read(), head[i] = 0;
for (int i = 1; i <= n; i++) w[i] = read();
for (int i = 1; i <= n; i++) {
if (a[i] < a[b[i]]) dis[i] = 1;
else if (a[i] >= a[b[i]] + w[b[i]]) dis[i] = 0;
else addEdge(b[i], i);
}
for (int i = 1; i <= n; i++) if (dis[i] == 1) dfs(i);
for (int i = 1; i <= n; i++) {
if (dis[i] == 0) printf("%lld ", a[i]);
else printf("%lld ", (a[i] + w[i] * qpow(fac[dis[i]], mod - 2) % mod) % mod);
}
puts("");
}
return 0;
}