Covered Walkway HDU - 4258(斜率dp)

传送门

题意:直接看题意即可

题解:本文主要得益于传送门,以及附上两篇论文论文一论文二

而本篇主要介绍这个题的推导过程,首先设dp[i]为到了第i个点的最小花费,得到

dp[i]=min(dp[j]+(a[i]-a[j+1])^2)+c(j<i),展开后得到

dp[i]=min(dp[j]+a[i]^2-2*a[i]a[j+1]+a[j+1]^2)+c,将无关项从min中拿出来,得到

dp[i]=min(dp[j]-2*a[i]a[j+1]+a[j+1]^2)+a[i]^2+c,这样现在主要分析下min里的东西

设y=dp[j]+a[j+1]^2,x=a[j+1],k=2*a[i],然后设

G=y-k*x,稍微变形下

y=k*x+G,为了使得dp[j]最小,也就是为了使得G最小,因为(x,y)在以前我们都推出来了,所以直接用单调队列维护下凸包跑出答案即可,具体证明见上面链接。

附上代码:


#include<bits/stdc++.h>

using namespace std;

typedef long long ll;

ll getll()
{
    char ch=' ';
    while(ch<'0'||ch>'9'){
        ch=getchar();
    }
    ll x=0;
    while(ch>='0'&&ch<='9'){
        x=x*10+ch-'0';ch=getchar();
    }
    return x;
}

const int maxn=1e6+5;

struct point{
    ll x,y;
    point(ll x=0,ll y=0):x(x),y(y){}
};
point q[maxn];

ll multi(point o,point a,point b)
{
    return (a.x-o.x)*(b.y-o.y)-(a.y-o.y)*(b.x-o.x);
}

ll dp[maxn];
int head,tail;
ll x[maxn];
int n,c;

inline ll sqr(ll x)
{
    return x*x;
}

int main()
{
    while(scanf("%d%d",&n,&c)&&(n||c)){
        memset(x,0,sizeof(x));
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++){
            x[i]=getll();
        }
        head=tail=0;
        q[tail++]=point(x[0],sqr(x[0]));
        dp[0]=c;
        for(int i=1;i<n;i++){
            point pp(x[i],dp[i-1]+sqr(x[i]));
            while(head+1<tail&&multi(q[tail-2],q[tail-1],pp)<0){
                tail--;
            }
            q[tail++]=pp;
            while(head+1<tail&&q[head].y-2*x[i]*q[head].x>=q[head+1].y-2*x[i]*q[head+1].x){
                head++;
            }
            dp[i]=q[head].y-2*x[i]*q[head].x+x[i]*x[i]+c;
        }
        printf("%I64d\n",dp[n-1]);
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值