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

思路:

       题目中注意的几点:

       (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;
}

          

你可能感兴趣的:(HDU 4258 Covered Walkway【单调队列斜率优化】)