问题明显可以转化成:给你n个数,选K个不相邻的数,使其和最小
K==1时,一定选最小值
K==2时,要么选最小+次小
要么选最小旁边的两个数,不可能最小旁边的两个数只选一个,否则为什么不选最小呢?
有了这个贪心策略我们就可以搞K==n的情况了。
建一个链表,把这n个数链起来。
再开一个小根堆。
每次操作取出堆顶的数。a[i]
1.把这个数前驱和后继从链表中和堆中删除
2.新建一个权值为这个数前驱和后继的和减去这个数的结点,指向前驱的前驱,后继的后继
3.同时把这个数丢到堆里。
重复上述操作
每次的操作相当于处理一个新的子问题:长度为n-i的序列选出K-i个数,使其和的值最小。
第二次选择id的数时相当于选择其周围2个数,并撤销对id的选择(包括其进行的操作)
比如 id表示: 选46不选5(但此时id的值为:3+7-(4+6-5)) ,如果这时候选择了id相当于选357不选46.
而且保证了每次选择多一个数,每次都是最优解。最终一定也是最优解/
注意:最左边前驱和最右边的后继要设成无穷大。
以为一旦选了边界的数,就不可能选次边界的数了,大家可以想一想为啥。
#include <bits/stdc++.h>
using namespace std;
typedef long lon