第一次看斜率优化dp
http://www.cnblogs.com/ka200812/archive/2012/08/03/2621345.html
简略代码:
#include <bits/stdc++.h>
using namespace std;
#define maxn 200000
int dp[maxn],sum[maxn];
int getdp(int i,int j)
{
return dp[j]+m+(sum[i]-sum[j])*(sum[i]-sum[j]);
}
int getup(int j,int k) //yj-yk的部分
{
return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]);
}
int getdown(int j,int k) //xj-xk的部分
{
return 2*(sum[j]-sum[k]);
}
int main()
{
std::ios::sync_with_stdio(false);
int i;
while (cin>>n>>m)
{
for (int i=1;i<=n;i++) cin>>sum[i];
sum[0]=dp[0]=0;
for (int i=1;i<=n;i++) sum[i]+=sum[i-1];
h=1; t=0;
for (int i=1;i<=n;i++)
{
while (h<=t&&getup(q[h+1],q[h])<=
sum[i]*getdown(q[h+1],q[h])) h++;
dp[i]=getdp(i,q[h]);
while (h<=t&&getup(i,q[t-1])*getdown(q[t-1],q[t-2])<=
getup(q[t-1],q[t-2])*getdown(i,q[t-1])) t--;
}
cout<<dp[n];
}
}