bzoj 1597 [Usaco2008 Mar]土地购买——斜率优化dp

题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1597

又一道斜率优化dp。负数让我混乱。不过仔细想想还是好的。

  还可以方便地把那个负号放到x上。只要改一下slope里的一个负号,就变成正常舒服的递增了。

这道题的要点其实是一开始h=0。不能h=1。这样就能把dp[0]纳入考虑。这是需要的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=5e4+5;
int n,top,h,t,q[N];
ll dp[N];
struct Node{
    ll a,b;double k;
}r[N];
bool cmp(Node u,Node v){return u.a<v.a;}
double slope(int u,int v)
{
    return (dp[u]-dp[v])/(r[u+1].b-r[v+1].b);
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%lld%lld",&r[i].a,&r[i].b);
    sort(r+1,r+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        while(top&&r[i].b>=r[top].b)top--;
        r[++top].a=r[i].a;r[top].b=r[i].b;
    }
    h=0;t=0;
    for(int i=1;i<=top;i++)
    {
        while(h<t&&slope(q[h+1],q[h])>=-r[i].a)h++;
        dp[i]=dp[q[h]]+r[i].a*r[q[h]+1].b;
        while(h<t&&slope(i,q[t-1])>=slope(q[t],q[t-1]))t--;
        q[++t]=i;
//        printf("h:a=%d b=%d t:a=%d b=%d\n",r[q[h]].a,r[q[h]].b,r[q[t]].a,r[q[t]].b);
//        for(int i=1;i<=top;i++)printf("dp[%d]=%.0lf\n",i,dp[i]);
    }
    printf("%lld",dp[top]);
    return 0;
}

 

posted on 2018-06-19 14:48  Narh  阅读(67)  评论(0编辑  收藏  举报

导航