Robotruck
題目傳送:UVALive - 3938 - Robotruck
AC代碼:
#include <map>
#include <set>
#include <list>
#include <cmath>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <cctype>
#include <cstdio>
#include <string>
#include <vector>
#include <complex>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <sstream>
#include <utility>
#include <iostream>
#include <algorithm>
#include <functional>
#define LL long long
#define INF 0x7fffffff
using namespace std;
const int maxn = 100010;
int x[maxn], y[maxn];
int total_dist[maxn];//total_dist[i]表示從第1個垃圾開始,一次經過2,3,4等等最終到達垃圾i的總距離
int total_weight[maxn];//totaldist[i]表示從第1個垃圾開始,直到垃圾i的總重量
int dist2origin[maxn];//dist2origin(i)表示垃圾i到原點的距離,即|xi| + |yi|.
int q[maxn];//維護一個單調隊列
int d[maxn];//d[i]爲從原點出發,將前i個垃圾清理完並放進垃圾桶的最小距離
int fun(int i) {
return d[i] - total_dist[i + 1] + dist2origin[i + 1];
}
void init() {
memset(total_dist, 0, sizeof(total_dist));
memset(total_weight, 0, sizeof(total_weight));
memset(dist2origin, 0, sizeof(dist2origin));
memset(q, 0, sizeof(q));
memset(d, 0, sizeof(d));
}
int main() {
int T;
scanf("%d", &T);
while(T --) {
int n, c, w;
init();
scanf("%d %d", &c, &n);
total_dist[0] = total_weight[0] = x[0] = y[0] = 0;
for(int i = 1; i <= n; i ++) {//預處理
scanf("%d %d %d", &x[i], &y[i], &w);
dist2origin[i] = abs(x[i]) + abs(y[i]);
total_dist[i] = total_dist[i - 1] + abs(x[i] - x[i - 1]) + abs(y[i] - y[i - 1]);
total_weight[i] = total_weight[i - 1] + w;
}
int head = 1, rear = 1;
for(int i = 1; i <= n; i ++) {
while(rear >= head && total_weight[i] - total_weight[q[head]] > c) head ++;
d[i] = fun(q[head]) + total_dist[i] + dist2origin[i];
while(rear >= head && fun(i) <= fun(q[rear])) rear --;//更新滑動窗口
q[++ rear] = i;
}
printf("%d\n", d[n]);
if(T > 0) printf("\n");
}
return 0;
}