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

LA3983 捡垃圾的机器人

时间:2016-04-22 22:25:55      阅读:341      评论:0      收藏:0      [点我收藏+]

标签:

Problem C - Robotruck

Background

This problem is about a robotic truck that distributes mail packages to several locations in a factory. The robot sits at the end of a conveyer at the mail office and waits for packages to be loaded into its cargo area. The robot has a maximum load capacity, which means that it may have to perform several round trips to complete its task. Provided that the maximum capacity is not exceeded, the robot can stop the conveyer at any time and start a round trip distributing the already collected packages. The packages must be delivered in the incoming order.

The distance of a round trip is computed in a grid by measuring the number of robot moves from the mail office, at location (0,0), to the location of delivery of the first package, the number of moves between package delivery locations, until the last package, and then the number of moves from the last location back to the mail office. The robot moves a cell at a time either horizontally or vertically in the factory plant grid. For example, consider four packages, to be delivered at the locations (1,2), (1,0), (3,1), and (3,1). By dividing these packages into two round trips of two packages each, the number of moves in the first trip is 3+2+1=6, and 4+0+4=8 in the second trip. Notice that the two last packages are delivered at the same location and thus the number of moves between them is 0.

Problem

Given a sequence of packages, compute the minimum distance the robot must travel to deliver all packages.

Input

Input consists of multiple test cases the first line of the input contains the number of test cases. There is a blank line before each dataset. The input for each dataset consists of a line containing one positive integer C, not greater then 100, indicating the maximum capacity of the robot, a line containing one positive integer N, not greater than 100,000, which is the number of packages to be loaded from the conveyer. Next, there are N lines containing, for each package, two non-negative integers to indicate its delivery location in the grid, and a positive integer to indicate its weight. The weight of the packages is always smaller than the robot’s maximum load capacity. The order of the input is the order of appearance in the conveyer.

Output

One line containing one integer representing the minimum number of moves the robot must travel to deliver all the packages. Print a blank line between datasets.

Sample Input

1

 

10

4

1 2 3

1 0 3

3 1 4

3 1 4

Sample Output

14

 

一个机器人从(0,0)开始按照序号从小到大依次拣起n个坐标点上的垃圾(重量为ci),并回到原点。但是任何时候手上垃圾都不能超过重量C。任意两点距离为曼哈顿距离。求机器人行走的最短路程。

关键词:动态规划,单调队列优化

状态设计:数据量:n<=100 000,c<=100。二维dp状态空间不足,只能设计一维状态。dp[i]表示拣完第i个点垃圾回到原点的最短距离。

状态转移:枚举最后一次捡垃圾的起点。dp[i] = min{ dp[j] + dist2origin[j+1] + total_dist[i]-total_dist[j+1] + dist2origin[i]  |  0<=j<=i-1 && sum_weight[i]-sum_weight[j]<=c }

优化:复杂度过高,需要优化。简化dp表达式,将仅含i的表达式提出来dp[i] = min{ dp[j]+dist2origin[j+1]-total_dist[j+1]  |  0<=j<=i-1 && sum_weight[i]-sum_weight[j]<=c } + total_dist[i] + dist2origin[i]

令func(j)=dp[j]+dist2origin[j+1]-total_dist[j+1],进一步简化为dp[i]=min{ func(j)  |  0<=j<=i-1 && sum_weight[i]-sum_weight[j]<=c} + total_dist[i] + dist2origin[i].

通过观察可以发现,对于任意的i,满足sum_weight[i]-sum_weight[j]<=c这个条件j总是一个连续区间。因为sum_weight[j]是递增的,因此sum_weight[i]-sum_weight[j]是递减的,较小的j若满足不等式,对于较大的j一定满足此式。

单调队列优化:更新询问滑动区间的最大值/最小值

http://www.cnblogs.com/FuTaimeng/p/5422891.html

 

代码如下:

#include<iostream>
#include<cmath>
#define Size 100005
using namespace std;

int d[Size];
int x[Size],y[Size];
int dist2origin[Size];
int total_weight[Size];
int total_dist[Size];
int q[Size];
int n,c;

inline int func(int i){ return d[i]-total_dist[i+1]+dist2origin[i+1]; }

int main(){
    freopen("31.in","r",stdin); 
    
    int T; cin>>T;
    while(T--){
        cin>>c>>n;
        total_dist[0]=total_weight[0]=x[0]=y[0]=0;
        int w;
        for(int i=1;i<=n;i++){
            cin>>x[i]>>y[i]>>w;
            dist2origin[i]=abs(x[i])+abs(y[i]);
            total_weight[i]=total_weight[i-1]+w;
            total_dist[i]=total_dist[i-1]+abs(x[i]-x[i-1])+abs(y[i]-y[i-1]);
        }
        
        int front=0,rear=0;
        for(int i=1;i<=n;i++){
            //弹出队首元素直到从front到i的质量之和大于c或者队列为空
            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(q[rear])>=func(i))rear--; 
            
            q[++rear]=i; 
        }
        
        cout<<d[n]<<endl; 
    }
    
    fclose(stdin);
    return 0;
} 

 

LA3983 捡垃圾的机器人

标签:

原文地址:http://www.cnblogs.com/FuTaimeng/p/5422963.html

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