http://acm.hdu.edu.cn/showproblem.php?pid=3507
5 5 5 9 5 7 5
230
/** hdu3507 斜率优化dp 膜拜大神:http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html */ #include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> using namespace std; const int N=500005; int dp[N]; int q[N]; int sum[N]; int head,tail,n,m; int get_dp(int i,int j) { return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]); } int get_up(int j,int k) { return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]); } int get_down(int j,int k) { return 2*sum[j]-2*sum[k]; } int main() { while(~scanf("%d%d",&n,&m)) { for(int i=1; i<=n; i++) scanf("%d",&sum[i]); sum[0]=dp[0]=0; for(int i=1; i<=n; i++) sum[i]+=sum[i-1]; head=tail=0; q[tail++]=0; for(int i=1; i<=n; i++) { while(head+1<tail&&get_up(q[head+1],q[head])<=sum[i]*get_down(q[head+1],q[head])) head++; dp[i]=get_dp(i,q[head]); while(head+1<tail&&get_up(i,q[tail-1])*get_down(q[tail-1],q[tail-2])<=get_up(q[tail-1],q[tail-2])*get_down(i,q[tail-1])) tail--; q[tail++]=i; } printf("%d\n",dp[n]); } return 0; }