hdu 3507 斜率dp
思路:dp[i]=dp[j]+(sum[i]-sum[j])^2+m;
剩下的就是普通斜率dp做法。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #include<cmath> #define Maxn 500010 #define LL __int64 using namespace std; LL dp[Maxn],num[Maxn],sum[Maxn]; int que[Maxn*2]; LL getleft(int j,int k) { return dp[j]+sum[j]*sum[j]-(dp[k]+sum[k]*sum[k]); } LL getright(int j,int k) { return 2*(sum[j]-sum[k]); } int main() { int n,m,i,j,head,rear; while(scanf("%d%d",&n,&m)!=EOF){ memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++){ scanf("%I64d",num+i); sum[i]=sum[i-1]+num[i]; } head=1,rear=0; que[++rear]=0; for(i=1;i<=n;i++){ while(head<rear&&getleft(que[head+1],que[head])<sum[i]*getright(que[head+1],que[head])) head++; dp[i]=dp[que[head]]+(sum[i]-sum[que[head]])*(sum[i]-sum[que[head]])+m; while(head<rear&&getleft(i,que[rear])*getright(que[rear],que[rear-1])<=getleft(que[rear],que[rear-1])*getright(i,que[rear])) rear--; que[++rear]=i; } printf("%I64d\n",dp[n]); } return 0; }