一样的套路
有一个office数量为
p
的限制很烦,当设一个office时,我们增加一个价值
瞎DP是
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N=310;
int n,m,a[N];
long long f[N][N];
int g[N][N];
int solve(int x){
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++) f[i][j]=1LL<<60,g[i][j]=0;
f[0][0]=0;
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++)
if(f[i-1][j]+a[i]-a[j]<f[i][j])
f[i][j]=f[i-1][j]+a[i]-a[j],g[i][j]=g[i-1][j];
int p=i; long long cur=0;
for(int j=i-1;~j;j--){
cur-=(i-p)*(a[j+1]-a[j]);
while((a[p-1]-a[j]>a[i]-a[p-1] || !j) && p>j && p>1)
cur+=a[i]-a[p-1]-(a[p-1]-a[j]),p--;
if(f[i-1][j]+cur+x<f[i][i])
f[i][i]=f[i-1][j]+cur+x,g[i][i]=g[i-1][j]+1;
}
}
long long mn=1LL<<30;
int ret;
for(int i=1;i<=n;i++)
if(f[n][i]<mn) mn=f[n][i],ret=g[n][i];
return ret;
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
int L=0,R=1e9,mid,cst;
while(L<=R)
solve(mid=L+R>>1)<=m?R=(cst=mid)-1:L=mid+1;
solve(cst);
int ans=1<<30;
for(int i=1;i<=n;i++)
if(f[n][i]<ans) ans=f[n][i];
printf("%d\n",ans-m*cst);
return 0;
}