考点
题解
见思路
思路
每次要找子序列中最接近当前元素的值,肯定希望其有序
平衡树
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
| #include <bits/stdc++.h> using namespace std; #define INF_MAX 0x3f3f3f3f #define INF_MIN 0xc0c0c0c0 multiset<int> s;
int main() { int n, in, ans = 0; cin >> n >> ans; s.emplace(ans), s.emplace(INF_MAX), s.emplace(INF_MIN); for (int i = 2; i <= n; ++i) { cin >> in; multiset<int>::iterator it = s.lower_bound(in); ans += min(abs(in - *it), abs(in - *prev(it))); s.emplace(in); } cout << ans; return 0; }
|
链表
先建立结构体,记录第几天及该天的营业额,并按照营业额排序
新建数组money
,效果和结构体一样,下标为第几天,值为该天营业额
根据排序后的结构体数组中的天数,建立双向链表
这样一来,每次先从天数大的开始,从数组money
获取其营业额并与相邻节点比较;比较结束后,将其删除
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
| #include <bits/stdc++.h> using namespace std; const int LEN = 1e5 + 10; int pre[LEN], nxt[LEN], money[LEN]; struct Node { int money_, day_; } arr[LEN];
int main() { int n, ans = 0; cin >> n; for (int i = 1; i <= n; ++i) { cin >> arr[i].money_; arr[i].day_ = i; money[i] = arr[i].money_; } sort(arr + 1, arr + 1 + n, [](Node &a, Node &b) -> bool { return a.money_ < b.money_; }); for (int i = 1; i <= n; ++i) { pre[arr[i].day_] = arr[i - 1].day_; nxt[arr[i].day_] = arr[i + 1].day_; } for (int day = n; day >= 1; --day) { int l = pre[day], r = nxt[day], now = money[day]; if (l && r) ans += min(abs(now - money[l]), abs(now - money[r])); else if (!l && r) ans += abs(now - money[r]); else if (l && !r) ans += abs(now - money[l]); else ans += now; nxt[l] = r; pre[r] = l; } cout << ans; return 0; }
|