F[0/1][i][j]表示i不取/取,i和i之前共取了j个的最小距离,wqs二分,最后那个特判0略显有毒
#include<cstdio>
#include<cstring>
using namespace std;
int n,k,s[1000005];
struct node{
long long val;
int num;
}F[2][100005];
node check(long long key){
for (int i=1; i<=n+1; i++) F[0][i]=F[1][i]=(node){1e9,1e9};
F[0][1]=(node){0,0};
for (int i=2; i<=n+1; i++){
if (F[0][i-1].val<F[1][i-1].val || F[0][i-1].val==F[1][i-1].val && F[0][i-1].num<=F[1][i-1].num) F[0][i]=F[0][i-1];
else F[0][i]=F[1][i-1];
F[1][i]=(node){F[0][i-1].val+s[i]-s[i-1]-key,F[0][i-1].num+1};
}
return F[0][n+1];
}
int main(){
scanf("%d%d",&n,&k);
long long L=0,R=0;
for (int i=1; i<=n; i++){
scanf("%d",&s[i]);
R+=s[i];
}
while (L<R){
long long mid=(L+R+1)>>1;
if (check(mid).num<=k) L=mid;
else R=mid-1;
}
if (check(L).num<=k) printf("%lld
",F[0][n+1].val+L*k);
else printf("0
");
return 0;
}