uva1169 Robotruck

题目链接:uva1169

题意:有一个机器人要按照编号从小到大的顺序捡起所有垃圾并扔进垃圾桶,可以一次捡起几个,但不能超过最大载重,求最短总路程。

根据大白书上写的,d[i]=min(d[j]-total_dist[j+1]+dist2origin[j+1])+total_dist[i]+dist2origin[i];

所以我们要找到func(j)=d[j]-total_dist[j+1]+dist2origin[j+1]的最小值

如果走到当前点i能走到队列中哪个点,队列中最小的走不到,就把最小的出队,然后继续判断(这个队列是递增的),一直找到能够走到了,这时的func一定最小(走到前一个点肯定比后一个点小),进入队列时把比这个元素大的全部删掉,这个比其他的元素小,所以当然不会用其他的元素。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const int MAXN=100010;
int x[MAXN],y[MAXN],total_dist[MAXN],total_weight[MAXN],dist2origin[MAXN];
int q[MAXN],d[MAXN];
int func(int i)
{
    return d[i]-total_dist[i+1]+dist2origin[i+1];
}
int main()
{
    int i,t,c,n,w,front,rear;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&c,&n);
        total_dist[0]=total_weight[0]=x[0]=y[0]=0;
        for(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;
        }
        front=rear=1;
        for(i=1;i<=n;i++)
        {
            while(front<=rear&&total_weight[i]-total_weight[q[front]]>c)
                front++;
            d[i]=func(q[front])+total_dist[i]+dist2origin[i];
            while(front<=rear&&func(i)<=func(q[rear]))
                rear--;
            q[++rear]=i;
        }
        printf("%d\n",d[n]);
        if(t)
            printf("\n");
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值