题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1911
相当明显的斜率优化,很好做;
注意slp里面要有(double),以免出现精度问题。
代码如下:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; typedef long long ll; int const maxn=1e6+5; ll n,a,b,c,s[maxn],q[maxn],f[maxn]; ll y(int i){return f[i]+a*s[i]*s[i]-b*s[i];} double slp(int i,int j){return (double)(y(j)-y(i))/(s[j]-s[i])/2/a;}//在这里/2/a int main() { scanf("%lld%lld%lld%lld",&n,&a,&b,&c); for(int i=1;i<=n;i++) scanf("%lld",&s[i]),s[i]+=s[i-1]; int head=1,tail=1; for(int i=1;i<=n;i++) { while(head<tail&&slp(q[head],q[head+1])<=s[i])head++;//则这里没有*2*a,否则需要区分a的正负 int j=q[head]; double tmp=s[i]-s[j]; f[i]=f[j]+a*tmp*tmp+b*tmp+c; while(head<tail&&slp(q[tail-1],q[tail])>slp(q[tail-1],i))tail--;// q[++tail]=i; } printf("%lld",f[n]); return 0; }