dp
第一眼看到这道题还以为是标准的划分dp,弄了好久时间复杂度还是超
现在总算懂了,这题是的dp
首先我们需要排序,把这些元素从小到大排好,这样确保可以直接划分(自己想一下),并且这一段的最大值是这一段的尾,最小值是这一段的头,相当于连区间最大值最小值的线段树都不用打了
用表示前
个元素以
为尾划分段后的最小值
那么可以是把前一个段的尾巴拆下,装到自己这里,也就是把上一段的尾延伸到第
个元素范围是
~
同时也可以作为新一段的尾,范围是 ~
那动态转移方程式就是
我们要确保最开始的个必须组成一个段,最优值后面还可以拆,但是前
元素不能再拆,所以
是从
开始的
贴上蒟蒻代码:
#include<bits/stdc++.h>
#define maxn 300010
#define INF 999999999
using namespace std;
int n,k;
int a[maxn],f[maxn];
int main(){
scanf("%d%d",&n,&k);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
sort(a+1,a+n+1);
for(int i=1;i<=n;++i) f[i]=INF;
f[k]=a[k]-a[1];
for(int i=k+1;i<=n;++i)
f[i]=min(f[i-1]-a[i-1]+a[i],f[i-k]-a[i-k+1]+a[i]);
printf("%d",f[n]);
return 0;
}

京公网安备 11010502036488号