HDU 4258 Covered Walkway【单调队列斜率优化】

来源:互联网 发布:手机nfc门禁软件 编辑:程序博客网 时间:2024/06/06 02:43

思路:

       题目中注意的几点:

       (1)The points will be in order, from smallest to largest(各点已经排序)

         (2)Note that it is possible for x=y. If so, then the contractor would simply charge c

     状态转移方程:

         dp[i]=min{dp[j]+(x[i]-x[j+1])^2+c}(0<j<=i-1)

         (dp[i]表示前i个点的花费)

     AC代码: 

#include<stdio.h>#define N 1000005_int64  x[N];_int64 dp[N];int q[N];int head,tail;_int64 c;int n;_int64 getDp(int i,int j){     return dp[j]+c+(x[i]-x[j+1])*(x[i]-x[j+1]);}_int64 getUp(int j,int k){     return dp[j]+x[j+1]*x[j+1]-(dp[k]+x[k+1]*x[k+1]);}_int64 getDown(int j,int k){     return 2*(x[j+1]-x[k+1]);}int main(){int i;while(scanf("%d%I64d",&n,&c)!=-1&&(n+c)){    for(i=1;i<=n;i++)scanf("%d",&x[i]);dp[0]=0;head=tail=0;q[tail++]=0;for(i=1;i<=n;i++){ while(head+1<tail&&getUp(q[head+1],q[head])<=x[i]*getDown(q[head+1],q[head])) head++; dp[i]=getDp(i,q[head]); while(head+1<tail&&getUp(q[tail-1],q[tail-2])*getDown(i,q[tail-1])>=getUp(i,q[tail-1])*getDown(q[tail-1],q[tail-2])) tail--; q[tail++]=i;}printf("%I64d\n",dp[n]);}    return 0;}

          

原创粉丝点击