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;
}

原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12831605.html