斜率优化DP
5 5 5 9 5 7 5
230
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=500500; int n; int q[maxn],head,tail; int dp[maxn],sum[maxn],M; int main() { while(scanf("%d%d",&n,&M)!=EOF) { head=0,tail=0,dp[0]=0,sum[0]=0; q[tail++]=0; for(int i=1;i<=n;i++) { scanf("%d",sum+i); sum[i]+=sum[i-1]; } for(int i=1;i<=n;i++) { while(head+1<tail) { int p1=q[head]; int p2=q[head+1]; int x1=dp[p1]+sum[p1]*sum[p1]; int x2=dp[p2]+sum[p2]*sum[p2]; int y1=sum[p1]; int y2=sum[p2]; if( (x2-x1) <= (y2-y1) * 2 * sum[i] ) head++; else break; } int k=q[head]; dp[i]=dp[k]+(sum[i]-sum[k])*(sum[i]-sum[k])+M; while(head+1<tail) { int p1=q[tail-2]; int p2=q[tail-1]; int p3=i; int x1=dp[p1]+sum[p1]*sum[p1]; int x2=dp[p2]+sum[p2]*sum[p2]; int x3=dp[p3]+sum[p3]*sum[p3]; int y1=sum[p1],y2=sum[p2],y3=sum[p3]; if((x3-x2)*(y2-y1)<=(x2-x1)*(y3-y2)) tail--; else break; } q[tail++]=i; } printf("%d\n",dp[n]); } return 0; }
HDOJ 3507 Print Article,布布扣,bubuko.com
原文:http://blog.csdn.net/ck_boss/article/details/38665835