1 条题解
-
0
一、题意理解
有 个人,初始排成一队,相邻两人相距 米,正常速度 米/秒。
规则:
- 队伍最后一人要用自己的“最高速度”跑到超过队伍最前面的人 米,然后回到队尾并恢复速度 。
- 每个人有一个初始最高速度 ,但每轮会衰减 :如果他是第 个跑的,那么他这轮的最高速度是 。
- 初始顺序是随机的( 种等可能),一轮是指每个人都当过一次最后一名并完成一次冲刺。
- 求一轮的期望时间。
二、单次追赶时间分析
假设当前队伍长度是 米( 个人, 段间隔,所以 )。
最后一人从队尾到超过队首 米,需要多跑的距离为: [ \text{额外距离} = L + u = (n-1)u + u = n u ] 因为最后一人原本在队尾,队首在前面 米处,要超过 米,所以相对位移是 。
相对速度计算
队伍正常速度是 ,最后一人冲刺速度是 (假设他是第 个跑的)。
相对速度 = 冲刺速度 − 队伍速度: [ v_{\text{rel}} = (c_i - (k-1)d_i) - v ] 追赶 米所需时间: [ t = \frac{n u}{c_i - (k-1)d_i - v} ] (这里假设 ,题目保证)
三、一轮的总时间
设初始排列为 ( 是队员编号)。
第 个跑的人是 ,他的最高速度是: [ c_{p_k} - (k-1) d_{p_k} ] 他跑步的时间是: [ T_k = \frac{n u}{c_{p_k} - (k-1) d_{p_k} - v} ] 一轮总时间: [ T_{\text{total}}(p) = \sum_{k=1}^n \frac{n u}{c_{p_k} - (k-1) d_{p_k} - v} ]
四、期望时间
因为排列是随机的,期望时间: [ E = \frac{1}{n!} \sum_{p \in \text{permutations}} \sum_{k=1}^n \frac{n u}{c_{p_k} - (k-1) d_{p_k} - v} ] 交换求和顺序: [ E = \sum_{k=1}^n \frac{1}{n!} \sum_{p} \frac{n u}{c_{p_k} - (k-1) d_{p_k} - v} ]
对于固定的 , 可以是任意一个人 ,并且每种 出现在位置 的概率是 (因为随机排列,对称性)。
所以: [ E = \sum_{k=1}^n \frac{1}{n} \sum_{i=1}^n \frac{n u}{c_i - (k-1) d_i - v} ] 化简: [ E = \sum_{k=1}^n \sum_{i=1}^n \frac{u}{c_i - (k-1) d_i - v} ]
五、最终公式
[ \boxed{E = u \sum_{i=1}^n \sum_{k=1}^n \frac{1}{c_i - (k-1) d_i - v}} ]
其中 表示这个队员是第 个跑的。
六、样例验证
样例输入:
10 37.618 0.422 72.865 126.767 202.680 106.102 99.516 134.418 167.952 173.646 120.210 136.571 2.941 3.664 7.363 4.161 0.246 8.046 5.521 7.473 7.178 5.649
我们计算: [ E = 0.422 \sum_{i=1}^{10} \sum_{k=1}^{10} \frac{1}{c_i - (k-1) d_i - 37.618} ]
用程序计算(注意数值稳定性):
n = 10 v = 37.618 u = 0.422 c = [72.865, 126.767, 202.680, 106.102, 99.516, 134.418, 167.952, 173.646, 120.210, 136.571] d = [2.941, 3.664, 7.363, 4.161, 0.246, 8.046, 5.521, 7.473, 7.178, 5.649] total = 0.0 for i in range(n): for k in range(1, n+1): denom = c[i] - (k-1)*d[i] - v total += 1.0 / denom E = u * total print(f"{E:.3f}")
运行得
0.815
,与样例一致。
七、算法复杂度
直接双重循环 , 可以接受。
八、最终代码(C++)
#include <iostream> #include <iomanip> #include <vector> using namespace std; int main() { int n; double v, u; cin >> n >> v >> u; vector<double> c(n), d(n); for (int i = 0; i < n; i++) cin >> c[i]; for (int i = 0; i < n; i++) cin >> d[i]; double ans = 0.0; for (int i = 0; i < n; i++) { for (int k = 1; k <= n; k++) { double denom = c[i] - (k-1) * d[i] - v; ans += u / denom; } } cout << fixed << setprecision(3) << ans << endl; return 0; }
- 1
信息
- ID
- 3309
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者