luogu P2120 [ZJOI2007]仓库建设 斜率优化dp

#include<iostream>
#include<cstring>
using namespace std;
#define int long long
const int N=1e6+10,INF=1e9;
int n,m;
int x[N];
int p[N];
int c[N];
int q[N];
int f[N];
int sump[N];//p[i]
int sum[N];//p[i]*x[i]
//f[i]=f[j]+c[i]+x[i]*sump[i]-x[i]sump[j]-sum[i]+sum[j]
//
double Y(int i)
{
	return f[i]+sum[i];
}
double X(int i)
{
	return sump[i];
}
double calc(int i,int j)
{
	return (Y(i)-Y(j))/(X(i)-X(j));
}
signed main()
{
	cin>>n;
	for(int i=1; i<=n; i++)
		cin>>x[i]>>p[i]>>c[i];
	for(int i=1; i<=n; i++)
	{
		sump[i]=sump[i-1]+p[i];
		sum[i]=sum[i-1]+p[i]*x[i];
	}
	int hh=0,tt=0;
	for(int i=1; i<=n; i++)
	{
		while(hh<tt && calc(q[hh],q[hh+1])<x[i])
			hh++;
		int j=q[hh];

		f[i]=f[j]+c[i]+x[i]*sump[i]-x[i]*sump[j]-sum[i]+sum[j];
		while(hh<tt && calc(q[tt],q[tt-1])>calc(i,q[tt-1]))
			tt--;
		q[++tt]=i;
	}
	cout<<f[n]<<endl;
	return 0;
}
posted @ 2020-05-07 23:05  晴屿  阅读(67)  评论(0编辑  收藏  举报