#斜率优化# [bzoj 2726] [SDOI2012]任务安排(执行时间可能是负数)

题目

#斜率优化dp# [poj 1180] Batch Scheduling题意相同。


解题思路

我并没有AC。
只是做了任务安排中执行时间可能是负数的情况。

如果执行时间可能是负数的话,那么sumTsumT不具有单调性,从而使斜率也不具有单调性。
所以我们不能只保留凸壳上“连接相邻两点的线段斜率”大于s+sumT[i]s+sumT[i]的部分。
而是必须维护整个凸壳。
这样的话,我们就不必要弹出对头,而是在单调队列里用二分查找最优决策。


代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std; 
int n,s,l,r,t,c,sumt[500001],sumc[500001],q[500001],f[500001]; 
int binary_search(int i,int k){
    if (l==r) return q[l]; 
    int L=l,R=r; 
    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(){
    scanf("%d%d",&n,&s) ; 
    for(int i=1;i<=n;i++) scanf("%d%d",&t,&c),sumt[i]=sumt[i-1]+t,sumc[i]=sumc[i-1]+c;
    l=r=1; q[1]=0; 
    for(int i=1;i<=n;i++){
        int p=binary_search(i,s+sumt[i]); 
        f[i]=f[p]-(s+sumt[i])*sumc[p]+sumt[i]*sumc[i]+s*sumc[n]; 
        while(l<r&&(f[q[r]]-f[q[r-1]])*(sumc[i]-sumc[q[r]])>=(f[i]-f[q[r]])*(sumc[q[r]]-sumc[q[r-1]])) r--; 
        q[++r]=i; 
    }
    printf("%d",f[n]); 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章