码迷,mamicode.com
首页 > 其他好文 > 详细

UVALive 3983 Robotruck

时间:2015-09-29 18:40:13      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:

如果状态定义为序号和重量的话,决策就是下一个垃圾捡或者不减,但是状态数太多了。

如果只定义序号作为状态的话,决策就变成从前面的某个j一直捡到i才送回垃圾。

这就变成了一个区间选最小值的问题,用单调队列维护。复杂度O(n)

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e5+5;
int x[maxn], y[maxn], w[maxn];
int sum_dist[maxn],sum_w[maxn],dist[maxn];
int dq[maxn],d[maxn];
inline int manhattan(int i,int j){ return abs(x[i]-x[j])+abs(y[i]-y[j]); }
inline int f(int i) { return d[i] - sum_dist[i+1] + dist[i+1]; }

//#define LOCAL
int main()
{
#ifdef LOCAL
    freopen("in.txt","r",stdin);
#endif
    //sum_dist[0] = 0;x[0] = y[0] = 0; d[0] = 0 dq[0] = 0
    int T; scanf("%d",&T);
    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+i);
            if(i>1) sum_dist[i] = sum_dist[i-1] + manhattan(i,i-1);
            sum_w[i] = sum_w[i-1] + w[i];
            dist[i] = manhattan(i,0);
        }
        int hd = 0,tl = 1;
        for(int i = 1; i <= n; i++){
            while(tl>hd && sum_w[i] - sum_w[dq[hd]] > C) hd++;
            d[i] = f(dq[hd]) + (sum_dist[i] + dist[i]);
            while(tl>hd && f(i) <= f(dq[tl-1])) tl--;
            dq[tl++] = i;
        }
        printf("%d\n",d[n]);
        if(T) putchar(\n);
    }
    return 0;
}

 

UVALive 3983 Robotruck

标签:

原文地址:http://www.cnblogs.com/jerryRey/p/4846949.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!