题目描述:
站台的长度是
L
,星之船最左侧的门称为第
如果第
i
个乘客从第
数据范围:
题解:
L
<script type="math/tex" id="MathJax-Element-6025">L</script> 很长,所以不能枚举每一个点,考虑有哪些必要枚举的点。可以证明只要枚举每个乘客在两个站点中点和车在最左和最右的位置就能找到解。考虑一个最优解车不在最左和最右位置并且没有乘客在两站点中点,那么每个乘客都有一个确定上车的门,我们对于每一个乘客找到使他能够多走一点的方向(就是他上的门的反向),对于两个方向,必然有一个方向能使乘客走的总路程至少不减,直到移到边缘或有人移到两站中点。
#include<bits/stdc++.h>
typedef long long ll;
const int N = 305;
int n, m, cnt;
ll L, P[N], D[N], S[N * N * 2];
void add(int x) {if (x >= 0 && x <= L - D[n]) S[++cnt] = x;}
int main() {
scanf("%lld%d", &L, &m); L <<= 1;
for (int i = 1; i <= m; i++)
scanf("%lld", &P[i]), P[i] <<= 1;
scanf("%d", &n);
for (int i = 2; i <= n; i++)
scanf("%lld", &D[i]), D[i] <<= 1;
for (int i = 1; i <= m; i++)
for (int j = 1; j < n; j++)
add(P[i] - (D[j] + D[j + 1]) / 2);
add(0); add(L - D[n]);
std::sort(S + 1, S + cnt + 1);
ll ans = 0, det;
for (int k = 1; k <= cnt; k++) {
int p = 1;
ll tans = 0;
for (int i = 1; i <= m; i++) {
while (p < n && abs(D[p + 1] + S[k] - P[i]) < abs(D[p] + S[k] - P[i])) p++;
tans += abs(D[p] + S[k] - P[i]);
}
if (tans > ans)
ans = tans,
det = S[k];
}
printf("%.1f %.1f\n", det * 0.5, ans * 0.5);
return 0;
}
如有侵权,请联系作者删除。