[SDOI2016]征途

[SDOI2016]征途

这个就当做斜率优化的模板吧..

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int N=3010;
ll f[N][N],a[N],l,r,q[N],n,m,sum[N];
inline int read()
{
    int x=0,ff=1;
    char ch=getchar();
    while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
    while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    return x*ff;
}
inline ll Y(int j,int x) {return sum[x]*sum[x]*m+f[x][j];}
inline ll X(int x) {return sum[x];}
inline double xie(int j,int x1,int x2)
{
    return (double)(Y(j,x1)-Y(j,x2))/(double)(X(x1)-X(x2)); 
}
int main()
{
    freopen("1.in","r",stdin);
    n=read();m=read();
    for(int i=1;i<=n;++i) a[i]=read(),sum[i]=sum[i-1]+a[i];
    memset(f,0x3f,sizeof(f));
    f[0][0]=0;
    for(int j=1;j<=m;++j)
    {
        q[l=r=0]=0;
        for(int i=1;i<=n;++i)
        {
            while(l<r&&xie(j-1,q[l+1],q[l])<=2*sum[i]*m) ++l;
            if(l<=r) f[i][j]=f[q[l]][j-1]+(sum[i]-sum[q[l]])*(sum[i]-sum[q[l]])*m;
            while(l<r&&xie(j-1,i,q[r])<=xie(j-1,q[r],q[r-1])) --r;
            q[++r]=i; 
            //cout<<i<<' '<<j<<' '<<f[i][j]<<endl;
        }
    }
    printf("%lld",f[n][m]-sum[n]*sum[n]);
    return 0;
} 
View Code

打了很多格式,发现就这种格式最不容易出错了..

之后,就是有时候做题,要搞清楚在干什么,就像这道题,m放里面与放外面是完全不一样的..

posted @ 2020-03-06 22:30  逆天峰  阅读(166)  评论(0编辑  收藏  举报
作者:逆天峰
出处:https://www.cnblogs.com/gcfer//