HDU 4258 Covered Walkway

斜率优化DP:
未优化方程:dp[i]=dp[j]+C+(a[i]-a[j+1])^2;
 
解法同HDU3507
 
Trick: 检查斜率时不能用叉乘 直接检查即可(不然数字范围过大超long long会WA)
 
代码:
 
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;

const int N=1000010;
typedef long long LL;


#define TOP que[ed-1],que[ed-2]
#define SEC que[ed-2],que[ed-3]
int n,c;
int a[N];
int que[N];
LL dp[N];
int st,ed;

LL F(int i,int j) {
    return dp[j]+(a[i]-a[j+1])*(a[i]-a[j+1])+c;
}

double G(int j,int k) {
    return (1.0*dp[j]-dp[k]+a[j+1]*1.0*a[j+1]-a[k+1]*1.0*a[k+1])/(1.0*a[j+1]-a[k+1]);
}

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

int main() {
    while(scanf("%d%d",&n,&c)&&(n||c)) {
        ed=st=0;
        getchar();
        for(int i=1;i<=n;i++) a[i]=nextInt();
        for(int i=1;i<=n;i++) {
            que[ed++]=i-1;
            while(ed-st>=3 && G(TOP)<=G(SEC) ) 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  编程菜菜  阅读(197)  评论(0编辑  收藏  举报