UVALive - 3983 - Robotruck (DP+單調隊列)

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