[hdu3507] Print Article

传送门
今天的斜率优化dp第二题,被自己坑了好长时间
一开始dp方程都错了,还过了样例。。。
正题,斜率方程其实很好推,就是细节比较坑,其它没什么难的,我不说思路了。

\[slope(j,k)=\frac {f_j-f_k+s_j^2-s_k^2} {s_j-s_k} \]

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline int read(){
	int x=0;char ch=' ';int f=1;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')f=-1,ch=getchar();
	while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
	return x*f;
}
int n,m;
ll c[500011],s[500011],f[500011],q[500011];
inline ll up(int j,int k){
	return (ll)(f[k]-f[j]+s[k]*s[k]-s[j]*s[j]);
}
inline ll down(int j,int k){
	return (ll)(s[k]-s[j]);
}
int main(){
	while(scanf("%d %d",&n,&m)==2){
		memset(f,0,sizeof(f));
		memset(q,0,sizeof(q));
		memset(s,0,sizeof(s));
		for(int i=1;i<=n;i++){
			c[i]=read();
			s[i]=s[i-1]+c[i];
		}
		int l=1,r=0;
		q[++r]=0;
		for(int i=1;i<=n;i++){
			while(l<r&&up(q[l],q[l+1])<=2*s[i]*down(q[l],q[l+1]))l++;
			f[i]=f[q[l]]+(s[i]-s[q[l]])*(s[i]-s[q[l]])+m;
			while(l<r&&up(q[r],i)*down(q[r-1],q[r])<=up(q[r-1],q[r])*down(q[r],i))r--;
			q[++r]=i;
		}
		printf("%lld\n",f[n]);
	}
	return 0;
}
posted @ 2017-09-25 20:38  玫葵之蝶  阅读(189)  评论(0编辑  收藏  举报