HDU 3507 Print Article

斜率优化DP入门题
 
O(n^2)方程 : dp[i]=dp[j]+M+(sum[i]-sum[j])^2;
 
用斜率优化掉枚举j的O(n)
 
代码(含输入输出外挂):

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

const int N=500010;
typedef long long LL;
#define TOP que[ed-1],que[ed-2]
#define SEC que[ed-2],que[ed-3]

LL a[N],que[N];
int n,m;
int st,ed;
LL dp[N];

LL Y(int j,int k) {
    return dp[j]-dp[k]+a[j]*a[j]-a[k]*a[k];
}
LL X(int j,int k) {
    return 2*(a[j]-a[k]);
}
LL F(int i,int j) {
    return dp[j]+m+(a[i]-a[j])*(a[i]-a[j]);
}


__inline LL nextInt() {
    LL ret=0;
    char c;
    while(1){
        c=getchar();
        if(c>='0'&&c<='9') ret=ret*10+c-'0';
        else break;
    }
    return ret;
}

int main() {
    while(scanf("%d%d",&n,&m)!=EOF) {
        getchar();
        for(int i=1;i<=n;i++) a[i]=nextInt();
        for(int i=1;i<=n;i++) a[i]+=a[i-1];
        dp[0]=0;
        st=ed=0;
        for(int i=1;i<=n;i++) {
            que[ed++]=i-1;
            while(ed-st>=3 && Y(TOP)*X(SEC)<=Y(SEC)*X(TOP)) que[ed-2]=que[ed-1],ed--;
            while(ed-st>=2 && F(i,que[st+1])<=F(i,que[st])) st++;
            dp[i]=F(i,que[st]);
        }
        printf("%I64d\n",dp[n]);
    }
    return 0;
}
posted @ 2012-08-28 23:16  编程菜菜  阅读(132)  评论(0编辑  收藏  举报