bzoj 4518

4518

思路:

  斜率优化;

代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define maxn 3005
#define ll long long
ll s[maxn],q[maxn],f[maxn][maxn];
bool getx(int i,int x1,int x2,int x3)
{
    return (-s[x2]*s[x2]-f[i-1][x2]+s[x1]*s[x1]+f[i-1][x1])*
    (2*s[x2]-2*s[x3])>(-s[x3]*s[x3]-f[i-1][x3]+s[x2]*s[x2]+
    f[i-1][x2])*(2*s[x1]-2*s[x2]);
}
ll getans(int i,int v,int k)
{
    return -2*s[v]*s[k]+s[k]*s[k]+f[i-1][k]+s[v]*s[v];
}
int main()
{
    int n,m;scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lld",&s[i]),s[i]+=s[i-1];
    memset(f,127,sizeof(f)),f[0][0]=0;
    for(int i=1;i<=m;i++)
    {
        int head=0,tail=1;
        for(int v=1;v<=n;v++)
        {
            while(head+2<=tail&&getx(i,q[tail-2],q[tail-1],q[tail]))
                q[tail-1]=q[tail],tail--;
            while(head<tail&&getans(i,v,q[head])>=getans(i,v,q[head+1])) head++;
            f[i][v]=getans(i,v,q[head]),q[++tail]=v;
        }
    }
    printf("%lld
",f[m][n]*m-s[n]*s[n]);
    return 0;
}
原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/7323740.html