zsyzlzy

导航

 

这是一道斜率优化简单题,但是他不给清楚数据范围。注意:0Ci0\le C_i。
不会斜率优化,请戳这里。
f[i]i,scf[i]表示对前i个单词进行处理的最低费用,s为c的前缀和
则有:f[i]=min   f[j]+(s[i]s[j])2+m  (0j<i)f[i]=min ~~~f[j]+(s[i]-s[j])^2+m ~~ (0\le j<i)
化成y=kx+b:y=kx+b:
f[j]+s[j]2=2s[i]s[j]+f[i]s[i]2+mf[j]+s[j]^2=2s[i]*s[j]+f[i]-s[i]^2+m
k,xk,x满足单调递增,即可用斜率优化做。
代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=5e5+10;
int n,m,q[N],l,r;
ll f[N],s[N];
double y(int i){return (double)f[i]+s[i]*s[i];}
double x(int i){return (double)s[i];}
double slope(int i,int j)
{
	return (y(i)-y(j))/(x(i)-x(j));
}
#define g getchar()
template<class o>//快读 
void qr(o&x)
{
	char c=g;bool v=x=0;
	while(!( ('0'<=c&&c<='9') || c=='-' ))c=g;
	if(c=='-')v=1,c=g;
	while('0'<=c&&c<='9')x=x*10+c-'0',c=g;
	if(v)x=-x;
}
#undef g
int main()
{
	while(~scanf("%d",&n))
	{
		qr(m);
		for(int i=1;i<=n;i++)
		{
			qr(s[i]);
			if(!s[i]){i--,n--;continue;}//坑点。
			s[i]=s[i]+s[i-1];
		}
		l=r=1;q[1]=0;
		#define j q[l]
		for(int i=1;i<=n;i++)
		{
			while(l<r&&slope(q[l],q[l+1])<=(double)(s[i]<<1))l++;
			f[i]=f[j]+(s[i]-s[j])*(s[i]-s[j])+m;
			while(l<r&&slope(q[r-1],q[r])>=slope(q[r],i))r--;
			q[++r]=i;
		}
		#undef j
		printf("%lld\n",f[n]);
	}
	return 0;
}
posted on 2019-07-01 11:27  zsyzlzy  阅读(89)  评论(0编辑  收藏  举报