題目
與#斜率優化dp# [poj 1180] Batch Scheduling題意相同。
解題思路
我並沒有AC。
只是做了任務安排中執行時間可能是負數的情況。
如果執行時間可能是負數的話,那麼不具有單調性,從而使斜率也不具有單調性。
所以我們不能只保留凸殼上“連接相鄰兩點的線段斜率”大於的部分。
而是必須維護整個凸殼。
這樣的話,我們就不必要彈出對頭,而是在單調隊列裏用二分查找最優決策。
代碼
#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]);
}