luogu P3628 [APIO2010]特别行动队 斜率优化dp
作者:互联网
#include<map>
#include<queue>
#include<time.h>
#include<limits.h>
#include<cmath>
#include<ostream>
#include<iterator>
#include<set>
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define rep_1(i,m,n) for(int i=m;i<=n;i++)
#define mem(st) memset(st,0,sizeof st)
typedef long long ll;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef pair<double,double> pdd;
const int inf = 0x3f3f3f3f;
const int N=1000010;
#define int long long
int q[N];
int n;
int sum;
int s[N],d[N],w[N];
int dp[N];
int a,b,c;
double Y(int i)
{
return dp[i]+a*s[i]*s[i]-b*s[i];
}
double K(int i)
{
return 2*a*s[i];
}
double X(int i)
{
return s[i];
}
double calc(int i,int j)
{
return 1.0*(Y(i)-Y(j))/(X(i)-X(j));
}
signed main()
{
int ans=2e9+1;
cin>>n>>a>>b>>c;
for(int i=1; i<=n; i++)
{
int x;
cin>>x;
s[i]=s[i-1]+x;
}
int hh=0,tt=0;
//dp[i]=max(dp[j]+a*(s[i]-s[j])^2+b*(s[i]-s[j])+c)
//dp[i]=dp[j]-2a*s[i]*s[j]+a*s[j]^2-b*s[j]+a*s[i]^2+b*s[i]+c
//2a*s[i]*s[j] + ,,, = dp[j]+a*s[j]*s[j]-b*s[j]
for(int i=1; i<=n; i++)
{
while(hh<tt && calc(q[hh],q[hh+1])>K(i))
hh++;
int j=q[hh];
dp[i]=dp[j]-2*a*s[i]*s[j]+a*s[j]*s[j]-b*s[j]+a*s[i]*s[i]+b*s[i]+c;
while(hh<tt && calc(i,q[tt-1])>calc(q[tt],q[tt-1]))
tt--;
q[++tt]=i;
}
cout<<dp[n]<<endl;
return 0;
}
标签:return,int,luogu,APIO2010,long,行动队,include,tt,dp 来源: https://www.cnblogs.com/QingyuYYYYY/p/12831605.html