zoukankan      html  css  js  c++  java
  • 【bzoj2726】[SDOI2012]任务安排 【cdq分治+斜率优化】

    题目传送门
    这题和bzoj1492Cash几乎一样,所以这里只贴公式。
    f[i]=min(f[j]+c[j](t[i]t[j]+s))
    =>f[k]+c[k]t[i]c[k](t[k]s)<=f[j]+c[j]t[i]c[j](t[j]s)
    =>f[k]+c[k]t[i]c[k]t[k]+c[k]s<=f[j]+c[j]t[i]c[j]t[j]+c[j]s
    =>(f[k]c[k]t[k]+c[k]s)(f[j]c[j]t[j]+c[j]s)<=(c[j]c[k])t[i]
    =>((f[k]c[k]t[k]+c[k]s)(f[j]c[j]t[j]+c[j]s))/(c[j]c[k])<=t[i]
    然后用cdq分治优化即可。
    细节详见代码。

    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    typedef long long ll;
    using namespace std;
    const int N=300005;
    int n,q[N];
    ll s,f[N];
    struct data{
        ll t,c;
        int id;
        friend bool operator < (const data &a,const data &b){
            return a.t<b.t;
        }
    }a[N],b[N];
    inline int rd(){
        register int res=0,f=1;
        register char ch=getchar();
        while(ch<'0'||ch>'9'){
            if(ch=='-'){
                f=-1;
            }
            ch=getchar();
        }
        while(ch>='0'&&ch<='9'){
            res=res*10+ch-'0';
            ch=getchar();
        }
        return res*f;
    }
    ll get(int i){
        return f[a[i].id]-a[i].c*a[i].t+a[i].c*s;
    }
    ll getx(int j,int k){
        return get(k)-get(j);
    }
    ll gety(int j,int k){
        return a[j].c-a[k].c;
    }
    void solve(int l,int r){
        if(l==r){
            return;
        }
        register int mid=(l+r)/2,j=l,k=mid+1;
        for(register int i=l;i<=r;i++){
            if(a[i].id<=mid){
                b[j++]=a[i];
            }else{
                b[k++]=a[i];
            }
        }
        for(register int i=l;i<=r;i++){
            a[i]=b[i];
        }
        solve(l,mid);
        j=1,k=0;
        for(register int i=l;i<=mid;i++){
            while(j<k&&getx(q[k],i)*gety(q[k-1],q[k])<getx(q[k-1],q[k])*gety(q[k],i)){
                k--;
            }
            q[++k]=i;
        }
        for(register int i=mid+1;i<=r;i++){
            while(j<k&&getx(q[j],q[j+1])<=a[i].t*gety(q[j],q[j+1])){
                j++;
            }
            if(j<=k){
                f[a[i].id]=min(f[a[i].id],f[a[q[j]].id]+a[q[j]].c*(a[i].t-a[q[j]].t+s));
            }
        }
        solve(mid+1,r);
        j=l,k=mid+1;
        for(register int i=l;i<=r;i++){
            if(j<=mid&&(k>r||a[j].c>=a[k].c)){
                b[i]=a[j++];
            }else{
                b[i]=a[k++];
            }
        }
        for(register int i=l;i<=r;i++){
            a[i]=b[i];
        }
    }
    signed main(){
        scanf("%d%lld",&n,&s);
        for(register int i=1;i<=n;i++){
            scanf("%lld%lld",&a[i].t,&a[i].c);
            a[i].t+=a[i-1].t;
            a[i].c+=a[i-1].c;
            a[i].id=i;
        }
        ll tmp=a[n].c;
        for(register int i=n;i>=0;i--){
            a[i].c=tmp-a[i].c;
        }
        for(register int i=1;i<=n;i++){
            f[i]=a[0].c*(a[i].t+s);
        }
        sort(a+1,a+n+1);
        solve(1,n);
        printf("%lld",f[n]);
        return 0;
    }
  • 相关阅读:
    15-数组concat()方法和push比较
    06-使用云储存上传工具
    05-云函数/云数据库的增删改查
    错题1
    c++链表
    8817
    8816
    1177
    1355
    c++期末考
  • 原文地址:https://www.cnblogs.com/2016gdgzoi471/p/9476886.html
Copyright © 2011-2022 走看看