您的位置:首页 > 其它

UVALive 3983 Robotruck (单调队列,dp)

2015-09-29 17:59 363 查看
如果状态定义为序号和重量的话,决策就是下一个垃圾捡或者不减,但是状态数太多了。

如果只定义序号作为状态的话,决策就变成从前面的某个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
);
if(T) putchar('\n');
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: