bzoj 2726 任务安排(3)/loj 10184-10186 斜率优化

任务安排1

#include<bits/stdc++.h>
#define int long long
using namespace std;

const int N=5050;
int n,s,t[N],c[N],f[N];
int sumt[N],sumc[N];

signed main(){
    scanf("%lld%lld",&n,&s);
    for(int i=1;i<=n;i++) scanf("%lld%lld",&t[i],&c[i]),sumt[i]=sumt[i-1]+t[i],sumc[i]=sumc[i-1]+c[i];
    memset(f,127,sizeof f);
    f[0]=0;
    for(int i=1;i<=n;i++){
        for(int j=0;j<i;j++)
        f[i]=min(f[i],f[j]+(sumc[i]-sumc[j])*sumt[i]+s*(sumc[n]-sumc[j]));
        //利用刷表法,将影响向后累加 
    }
    printf("%lld\n",f[n]);return 0;
}

任务安排2 数据规模变大

#include<cstdio>
#include<cstring>
#include<iostream>

using namespace std;

const int N=5050;

long long f[N],sumt[N],sumc[N];
int q[N],n,s;

int main(){
    scanf("%d%d",&n,&s);
    for(int i=1;i<=n;i++){
        int t,c;
        scanf("%d%d",&t,&c);
        sumt[i]=sumt[i-1]+t;
        sumc[i]=sumc[i-1]+c;
    }
    memset(f,0x3f,sizeof f);
    f[0]=0;
    int head=1,tail=1;
    q[1]=0;
    for(int i=1;i<=n;i++){
        while(head<tail&&f[q[head+1]]-f[q[head]]<=(s+sumt[i])*(sumc[q[head+1]]-sumc[q[head]])) head++;
        f[i]=f[q[head]]-(sumt[i]+s)*sumc[q[head]]+s*sumc[n]+sumt[i]*sumc[i];
        while(head<tail&&(f[q[tail]]-f[q[tail-1]])*(sumc[i]-sumc[q[tail]])>=(f[i]-f[q[tail]])*(sumc[q[tail]]-sumc[q[tail-1]])) tail--;
        q[++tail]=i;
    }
    printf("%d\n",f[n]);return 0;
}

任务安排3 T可能是负数

#include<bits/stdc++.h>

using namespace std;

const int N=300050;
long long sumt[N],sumc[N],f[N];
int q[N],n,s,head,tail;

int binarysearch(int i,int k){
    if(head==tail) return q[head];
    int l=head,r=tail;
    while(l<r){
        int mid=(l+r)>>1;
        if(f[q[mid+1]]-f[q[mid]]<=k*(sumc[q[mid+1]]-sumc[q[mid]])) l=mid+1;
        else r=mid;
    }return q[l];
} 
int main(){
    cin>>n>>s;
    for(int i=1;i<=n;i++){
        int t,c;
        cin>>t>>c;
        sumc[i]=sumc[i-1]+c;
        sumt[i]=sumt[i-1]+t;
    }
    head=tail=1;
    for(int i=1;i<=n;i++){
        int p=binarysearch(i,s+sumt[i]);
        f[i]=f[p]-(s+sumt[i])*sumc[p]+sumt[i]*sumc[i]+s*sumc[n];
        while(head<tail&&(f[q[tail]]-f[q[tail-1]])*(sumc[i]-sumc[q[tail]])>=(f[i]-f[q[tail]])*(sumc[q[tail]]-sumc[q[tail-1]])) tail--;
        q[++tail]=i;
    }
    cout<<f[n]<<endl;
    return 0;
}

 

posted @ 2018-09-24 15:00  ASDIC减除  阅读(101)  评论(0编辑  收藏  举报