【bzoj4518】征途

  • 本文为博主原创,未经许可不得转载

看到这题,我整个人都惊呆了,然后看了一下一句话题解,斜率优化

于是静下心来仔细推了推式子,发现真的是斜率优化

至于题解,网上很多,我就不写了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include<bits/stdc++.h>
#define FILE "read"
using namespace std;
typedef long long ll;
int n,m,a[3010],sum[3010],q[3010],f[3010][3010];
inline int read(){
int x=0,f=1; char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
double slop(int j,int k,int x){return (double)(f[j][x]-f[k][x]+sum[j]*sum[j]-sum[k]*sum[k])/(sum[j]-sum[k]);}
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
n=read(); m=read(); memset(f,10,sizeof(f));
for(int i=1;i<=n;++i) a[i]=read();
for(int i=1;i<=n;++i) sum[i]=sum[i-1]+a[i];
for(int i=1;i<=n;++i) f[i][1]=sum[i]*sum[i];
for(int j=2;j<=m;++j){
int head=0,tail=0;
for(int i=1;i<=n;++i){
while(head<tail&&slop(q[head],q[head+1],j-1)<(double)sum[i]*2) ++head;
int temp=q[head]; f[i][j]=f[temp][j-1]+(sum[i]-sum[temp])*(sum[i]-sum[temp]);
while(head<tail&&slop(q[tail],q[tail-1],j-1)>slop(i,q[tail],j-1)) --tail;
q[++tail]=i;
}
}
printf("%d\n",f[n][m]*m-sum[n]*sum[n]);
return 0;
}
文章目录
,