AtCoder Beginner Contest 095

D

根据贪心,只能有4种方式可以走。

  • 顺时针
  • 逆时针
  • 先顺时针后逆时针
  • 先逆时针后顺时针

记录前缀和和后缀和即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main()
{
ll n, c;
cin >> n >> c;
vector<ll> x(n + 2);
vector<ll> v(n + 2);
// 顺时针
// 逆时针
// 顺时针之后逆时针
// 逆时针之后顺时针
vector<ll> pmax(n + 2);
vector<ll> smax(n + 2);
vector<ll> psmax(n + 2);
vector<ll> spmax(n + 2);
for (int i = 1; i <= n; i++)
{
cin >> x[i] >> v[i];
}
for (int i = 1; i <= n; i++)
{
pmax[i] = v[i] - x[i] + x[i - 1] + pmax[i - 1];
}
x[n + 1] = c;
for (int i = n; i >= 1; i--)
{
smax[i] = v[i] - x[i + 1] + x[i] + smax[i + 1];
}
for (int i = 2; i <= n; i++)
{
pmax[i] = max(pmax[i - 1], pmax[i]);
}
for (int i = n - 1; i >= 1; i--)
{
smax[i] = max(smax[i + 1], smax[i]);
}
ll ans = 0;
for (int i = 1; i <= n; i++)
{
ans = max(pmax[i], ans);
ans = max(smax[i], ans);
ans = max(pmax[i] - x[i] + smax[i + 1], ans);
ans = max(smax[i] - (c - x[i]) + pmax[i - 1], ans);
}
cout << ans << '\n';
}