bzoj 1911

斜率优化题。
基础方程很容易就推了出来:

f[i]=max{f[j]+a(s[i]s[j])2+b(s[i]s[j])+c}

推斜率
k<j<i
若选j优于选k
f[j]+a(s[i]s[j])2+b(s[i]s[j])+cf[k]+a(s[i]s[k])2+b(s[i]s[k])+c
化啊化啊化
f[k]f[j]+a×s[k]2a×s[j]2b×s[k]+b×s[j]s[k]s[j]2×a×s[i]
代码呼之欲出
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

long long n,a,b,c,f[1000010],q[1000010],s[1000010];

double slp(long long k,long long j)
{
    return (double)(f[k]-f[j]+a*s[k]*s[k]-a*s[j]*s[j]-b*s[k]+b*s[j])/(s[k]-s[j]);
}
int main()
{
    scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
    s[0]=0;
    for(long long i=1;i<=n;i++)
    {
        long long x;
        scanf("%lld",&x);
        s[i]=s[i-1]+x;
    }
    long long st=0,ed=1;
    q[0]=0;
    f[0]=0;
    for(long long i=1;i<=n;i++)
    {
        while(st+1<ed&&slp(q[st],q[st+1])>2*a*s[i])
        st++;
        long long j=q[st];
        f[i]=f[j]+a*(s[i]-s[j])*(s[i]-s[j])+b*(s[i]-s[j])+c;
        while(st+1<ed&&slp(q[ed-2],q[ed-1])<slp(q[ed-1],i))
        ed--;
        q[ed++]=i;/*
        for(long long j=0;j<i;j++)
        f[i]=max(f[i],f[j]+a*(s[i]-s[j])*(s[i]-s[j])+b*(s[i]-s[j])+c);*/
    }
    printf("%lld",f[n]);
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值