題目描述
藍書上的例題,我重新推導一遍。
設
其中:
如果預處理出
設
那麼
用單調隊列維護
代碼
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn=100010;
int d[maxn],tot_d[maxn],tot_w[maxn],dist0[maxn],q[maxn],x[maxn],y[maxn],w;
int func(int i){
return d[i]-tot_d[i+1]+dist0[i+1];
}
int main(){
int t;
cin>>t;
x[0]=y[0]=tot_w[0]=tot_d[0]=q[0]=0;;
while(t--){
int c,n;
scanf("%d%d",&c,&n);
for(int i=1;i<=n;i++){
scanf("%d%d%d",&x[i],&y[i],&w);
tot_w[i]=w+tot_w[i-1];
tot_d[i]=abs(x[i]-x[i-1])+abs(y[i]-y[i-1])+tot_d[i-1];
dist0[i]=abs(x[i])+abs(y[i]);
}
int head=0,tail=1;
for(int i=1;i<=n;i++){
while(head<tail&&tot_w[i]-tot_w[q[head]]>c) head++;
d[i]=func(q[head])+tot_d[i]+dist0[i];
while(head<tail&&func(q[tail])>=func(i)) tail--;
q[++tail]=i;
}
printf("%d\n",d[n]);
if(t>0) puts("");
}
return 0;
}