思路:dp[i]=dp[j]+(num[i]-num[j+1])^2;
#include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define Maxn 1000010 #define LL unsigned __int64 using namespace std; LL dp[Maxn],num[Maxn]; int que[Maxn*3]; inline int ReadInt() { char ch = getchar(); int data = 0; while (ch < '0' || ch > '9') ch = getchar(); do { data = data*10 + ch-'0'; ch = getchar(); } while (ch >= '0' && ch <= '9'); return data; } int main() { int n,i,j; LL c; while(scanf("%d%I64u",&n,&c)!=EOF,n||c){ memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) num[i]=(LL)ReadInt(); int head,rear; head=1;rear=0; que[++rear]=0; dp[1]=0; for(i=1;i<=n;i++){ while(head<rear&&(dp[que[head+1]]+num[que[head+1]+1]*num[que[head+1]+1]-(dp[que[head]]+num[que[head]+1]*num[que[head]+1])<=2*num[i]*(num[que[head+1]+1]-num[que[head]+1]))) head++; dp[i]=dp[que[head]]+(num[i]-num[que[head]+1])*(num[i]-num[que[head]+1])+c; while(head<rear&&(dp[i]+num[i+1]*num[i+1]-(dp[que[rear]]+num[que[rear]+1]*num[que[rear]+1]))*(num[que[rear]+1]-num[que[rear-1]+1])<=(dp[que[rear]]+num[que[rear]+1]*num[que[rear]+1]-(dp[que[rear-1]]+num[que[rear-1]+1]*num[que[rear-1]+1]))*(num[i+1]-num[que[rear]+1])) rear--; que[++rear]=i; } printf("%I64u ",dp[n]); } return 0; }