单调队列优化dp(捡垃圾的机器人)
/************************************************************************* > File Name: a.cpp > Author: QWX > Mail: > Created Time: 2018/10/16 16:47:07 ************************************************************************/ //{{{ #include #include<iostream> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<queue> #include<map> #include<set> #include<cassert> #include<string> #include<cstring> #include<complex> //#include<bits/stdc++.h> #define vi vector<int> #define pii pair<int,int> #define mp make_pair #define pb push_back #define first fi #define second se #define pw(x) (1ll << (x)) #define sz(x) ((int)(x).size()) #define all(x) (x).begin(),(x).end() #define rep(i,l,r) for(int i=(l);i<(r);i++) #define per(i,r,l) for(int i=(r);i>=(l);i--) #define FOR(i,l,r) for(int i=(l);i<=(r);i++) #define cl(a,b) memset(a,b,sizeof(a)) #define fastio ios::sync_with_stdio(false);cin.tie(0); #define lson l , mid , ls #define rson mid + 1 , r , rs #define INF 0x3f3f3f3f #define LINF 0x3f3f3f3f3f3f3f3f #define ll long long #define ull unsigned long long #define dd(x) cout << #x << " = " << (x) << "," #define de(x) cout << #x << " = " << (x) << "\n" #define endl "\n" using namespace std; //}}} const int N=1e5+7; int dp[N],dist[N],dist_0[N],x[N],y[N],w[N],sw[N],que[N]; int n,C; inline int f(int j) { return dp[j-1]-dist[j]+dist_0[j]; } int solve() { cin>>C>>n; int h=1,t=0; cl(dp,0); FOR(i,1,n){ cin>>x[i]>>y[i]>>w[i]; sw[i]=sw[i-1]+w[i]; dist[i]=dist[i-1]+(abs(x[i]-x[i-1])+abs(y[i]-y[i-1])); dist_0[i]=abs(x[i])+abs(y[i]); while(h<=t&&f(i)<f(que[t]))t--; que[++t] = i; while(h<=t&&sw[i]-sw[que[h]-1]>C)h++; dp[i]=f(que[h])+dist[i]+dist_0[i]; } } int main() { int T;cin>>T; while(T--){ solve(); cout<<dp[n]<<endl; if(T)cout<<endl; } return 0; } /* 1 10 4 1 2 3 1 0 3 3 1 4 3 1 4 */