• BZOJ2726: [SDOI2012]任务安排


    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2726

    倒着做,前面的点对后面的点都是有贡献的。 f[i]=min(f[j]+cost[i]*(T[i]-T[j]+S)) (j>i)

    然后。。。。时间可以是负数的。(所以看起来好好的单调队列+斜率优化就变成了动态凸包。。x坐标并不是有序的。。

    用cdq分治处理。。

    (看起来是要逆序维护下凸包的。但是我比较蠢于是把序列翻转了一下这样就变成了正着做下凸包辣。。

    然后时间是负数的话,不等号的方向要改变。

    (虽然我在写的时候脑子一团浆糊。。但是感觉写出来的代码还不会太乱吧。。

    #include<cstring>
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    #include<map>
    #include<cmath>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define maxn 300500
    #define inf int(1e9)
    #define ll long long
    using namespace std;
    struct data{int x,k,id;ll y;
    }a[maxn],s[maxn],t[maxn];
    int n,S;
    ll f[maxn],bin[69];
    int cross(data a,data b,data c){
        int x1=b.x-a.x,x2=c.x-a.x;
        ll y1=b.y-a.y,y2=c.y-a.y;
        if ((x1<0)^(x2<0)) return y1*x2<=y2*x1;
        else return x1*y2-x2*y1<=0;
    }
    bool jud(data a,data b,int k){
        ll x=b.x-a.x,y=b.y-a.y;
        if (x<0) return y>x*k;
        else return y<x*k;
    }
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }    
    void cdq(int l,int r){
        if (l==r) {
            a[l].y=f[l];
            return;
        }
        int l1=l,l2=(l+r)/2+1,mid=(l+r)/2;
        rep(i,l,r) if (a[i].id<=mid) t[l1++]=a[i]; else t[l2++]=a[i];
        rep(i,l,r) a[i]=t[i];
        cdq(l,mid);
        int top=0;
        rep(i,l,mid){
            while (top>1&&cross(s[top-1],s[top],a[i])) top--;
            s[++top]=a[i];
        }
        int j=1;
        rep(i,mid+1,r){
            while (j<top&&jud(s[j],s[j+1],a[i].k)) j++;
            f[a[i].id]=min(f[a[i].id],1LL*a[i].k*(a[i].x-s[j].x+S)+f[s[j].id]);  
        }
        cdq(mid+1,r);
        l1=l,l2=mid+1;
        rep(i,l,r) if (l1<=mid&&(a[l1].x<a[l2].x||l2>r)) t[i]=a[l1++]; else t[i]=a[l2++];
        rep(i,l,r) a[i]=t[i];
    }
    int main(){
        n=read(); S=read();
        rep(i,1,n) a[i].x=read(),a[i].k=read();    
        down(i,n,1) a[i].x+=a[i+1].x,a[i].k+=a[i+1].k;
        rep(i,1,n/2) swap(a[i],a[n-i+1]);
        rep(i,1,n) f[i]=1LL*a[i].k*(a[i].x+S),a[i].id=i; f[0]=0;
        cdq(1,n);
        printf("%lld
    ",f[n]);
        return 0;
    }
  • 相关阅读:
    BZOJ-3940:Censoring(AC自动机裸题)
    BZOJ-3881:Divljak (AC自动机+DFS序+树链求并+树状数组)
    CodeForces
    CodeForces 547E:Mike and Friends(AC自动机+DFS序+主席树)
    CodeForces -163E :e-Government (AC自动机+DFS序+树状数组)
    CodeForces
    CodeForces
    BZOJ2726:任务安排(DP+斜率优化+二分)
    bzoj 2049: [Sdoi2008]Cave 洞穴勘测
    [SDOI2009]Bill的挑战
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5187406.html
Copyright © 2020-2023  润新知