#斜率優化# [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]); 
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章