题解 P4072 【[SDOI2016]征途】
bztMinamoto · · 题解
打广告->这里
推式子(快哭了……)
然后因为
我们发现
总算扯到dp上了不容易啊……
我们设
然后考虑斜率优化(以下省略
假设
展开,移项
然后就可以上斜率优化了
ps:注意当
//minamoto
#include<iostream>
#include<cstdio>
#define ll long long
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=0;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*10+num);
(flag)&&(res=-res);
#undef num
return res;
}
const int N=3005;
ll sum[N],sp[N],dp[N];int n,m,h,t,q[N],r;
inline ll Y(int i){return sp[i]+sum[i]*sum[i];}
inline double slope(int j,int k){
return (Y(j)-Y(k))*1.0/(sum[j]-sum[k]);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read(),m=read();
for(int i=1;i<=n;++i)
sum[i]=read()+sum[i-1],sp[i]=sum[i]*sum[i];
for(int a=1;a<m;++a){
h=t=0;q[0]=a;
for(int i=a+1;i<=n;++i){
while(h<t&&slope(q[h],q[h+1])<2*sum[i]) ++h;
dp[i]=sp[q[h]]+(sum[i]-sum[q[h]])*(sum[i]-sum[q[h]]);
while(h<t&&slope(q[t],q[t-1])>slope(q[t-1],i)) --t;q[++t]=i;
}
for(int i=1;i<=n;++i) sp[i]=dp[i];
}
printf("%lld\n",-sum[n]*sum[n]+m*dp[n]);
return 0;
}