Print Article HDU - 3507 斜率dp

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,m,c;
int q[N];
ll dp[N];
ll sum[N];
ll get_y(int j,int k)
{
	return dp[j]+sum[j]*sum[j]-dp[k]-sum[k]*sum[k];
}
ll get_x(int j,int k)
{
	return sum[j]-sum[k];
}
int main()
{
	while(cin>>n>>m)
	{
		sum[0]=0;
		for(int i=1;i<=n;i++)
		{
			cin>>c;
			sum[i]=sum[i-1]+c;
		}
		int l=0,r=0;
		dp[0]=q[0]=0;
		for(int i=1;i<=n;i++)
		{
			while(l<r && (get_y(q[l+1],q[l]))<=get_x(q[l+1],q[l])*sum[i]*2)
				l++;
			int j=q[l];
			dp[i] = dp[j]+(sum[i]-sum[j])*(sum[i]-sum[j])+m;
			while(l<r && get_y(i,q[r])*get_x(q[r],q[r-1]) <= get_y(q[r],q[r-1])*get_x(i,q[r]) )
				r--;
			q[++r]=i;  
		}
		cout<<dp[n]<<endl;
	}
}
posted @ 2020-03-17 19:41  晴屿  阅读(75)  评论(0编辑  收藏  举报