题意
给出一个常数a,b,c和数列{
找到一种分组方案使贡献和最大
解题报告
前两天写的没来得及写博客现在找不到推式子的草稿纸了…只好再推一遍…
斜率优化
设置状态
转移时若有
整理,得
局势渐渐明朗了…右边可以看做斜率的形式,左边与j,k无关
因为求最大,其实就是维护右边的斜率单调不减,单调队列维护一下就好了
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 1000005
#define LL long long
#define inf 1e18
using namespace std;
int n,q[N];
LL sum[N],a,b,c,f[N];
inline double calc(int x,int y){return (double)(f[x]-f[y]+a*(sum[x]*sum[x]-sum[y]*sum[y])+b*(sum[y]-sum[x]))/(double)(2*a*(sum[x]-sum[y]));}
int main(){
scanf("%d%lld%lld%lld",&n,&a,&b,&c);
for(int i=1;i<=n;++i) scanf("%lld",&sum[i]),sum[i]+=sum[i-1];
int l=0,r=0;
for(int i=1;i<=n;++i){
while(l<r&&calc(q[l],q[l+1])<sum[i]) ++l;
LL tmp=sum[i]-sum[q[l]];
f[i]=f[q[l]]+a*tmp*tmp+b*tmp+c;
while(l<r&&calc(q[r-1],q[r])>calc(q[r],i)) --r;
q[++r]=i;
}
printf("%lld\n",f[n]);
return 0;
}