BZOJ 4518: [Sdoi2016]征途

来源:互联网 发布:软件质量管理指南 编辑:程序博客网 时间:2024/04/30 10:45

裸的斜率优化DP

(似乎并没有精度问题啊)

#include<cstdio>#include<iostream>#include<cstring>#include<cmath>#include<queue>#include<vector>#include<algorithm>#include<map>#define rep(i,l,r) for(int i=l;i<=r;i++)#define per(i,r,l) for(int i=r;i>=l;i--)#define mmt(a,v) memset(a,v,sizeof(a))#define tra(i,u) for(int i=head[u];i;i=e[i].nedt)using namespace std;typedef long long ll;const int N=3000+5;int n,m,q[N],h,t,last,now;ll d[N],f[N][2];template<class T>T sqr(T d){return d*d;}double y(int i){return f[i][last]+m*sqr(d[i])+2*d[n]*d[i];}double x(int i){return 2*m*d[i];}double slope(int j,int k){return (y(j)-y(k))/(x(j)-x(k));}void refresh(int i){while(h<t&&slope(q[h+1],q[h])<d[i])h++;}void push(int i){while(h<t&&slope(i,q[t])<slope(q[t],q[t-1]))t--;q[++t]=i;}int main(){//freopen("a.in","r",stdin);scanf("%d%d",&n,&m);rep(i,1,n)scanf("%lld",&d[i]),d[i]+=d[i-1];now=0;last=1;rep(i,1,n)f[i][now]=m*sqr(d[i])+2*d[n]*(0-d[i]);rep(j,2,m){now^=1;last^=1;q[h=t=0]=j-1;rep(i,j,n){refresh(i);f[i][now]=f[q[h]][last]+sqr(d[i]-d[q[h]])*m+2*d[n]*(d[q[h]]-d[i]);//printf("%d %d %d\n",i,j,q[h]);push(i);}}printf("%lld\n",f[n][now]+sqr(d[n]));return 0;}


0 0