题目链接
https://www.lydsy.com/JudgeOnline/problem.php?id=1150
分析
选出的 K K K 组一定相邻,所以我们预处理出相邻两个办公楼的间距,共 N − 1 N - 1 N−1 个。
问题转化为挑出 K K K 个元素,使其和尽量小且互不相邻。
假设我们选择了其中最小的,就不能选其两边的;假如我们没有选择最小的,就一定会选择其两边的,否则,将选择的某个换成最小的会更优。
建一个链表和一个堆,满足其中元素对应,且对应元素之间可互达,每次挑出最小值,删除最小值及其两端元素。
然后加入一个新元素,其值为两边元素和减最小值,用来表示不选最小值而选两边元素的情况。
问题规模缩小,以此类推即可得出最终答案。
加入最小值在边界上,显然直接删除其与其相邻元素即可,即此时最小值必选。
AC代码
#include <cstdio>
#include <iostream>
using namespace std;
inline int read() {
int num = 0;
char c = getchar();
while (c < '0' || c > '9') c = getchar();
while (c >= '0' && c <= '9')
num = num * 10 + c - '0', c = getchar();
return num;
}
const int maxn = 1e5 + 5;
struct Node1 {
int v, l, r, p;
} l[maxn];
inline void del(int p) {
l[l