The slag is also in the effort to brush the white, although the basic of each problem can not be done, but each question is able to understand, and then achieve their own, and then write a report, I hope this method can be useful.
This problem gives the coordinates and weight of n garbage, then the maximum load of the robot is C, when picking up rubbish must be picked up in the order of garbage.
This problem comes up I think of backpack, either pick up, or go back, this method is actually can, but the complexity is relatively high, if the data comparison pits, may not be able to. But this is a question that can be.
The method described in white is a very ingenious monotone queue optimization.
The origin array is the distance from the original point I to Manhattan, and the total array is the distance along the garbage order to the garbage I.
D[i] means that the shortest distance required to return to the origin after garbage I is collected, so the answer is d[n],d[i]=d[j]+origin[j+1]+ (total[i]-total[j+1]) +origin[i]; Meet the j+ 1 garbage to the first I garbage weight and less than equals C
State transition equation: D[i]=min (d[j]+origin[j+1]-total[j+1]) +origin[i]+total[i].
Monotone queue optimization is to maintain a period of time, this interval of garbage weight is less than or equal to C, and the distance monotonically increment, study a new garbage I, if the garbage to the first element of the queue weight and greater than C, then the first element of the team will be discarded, because greater than C can not start from the first element of the team, POPs the first element, continues the first element of the expedition, until the weight of the queue and less than equals C. D[i]= from the beginning of the team first element to I distance (because this is a monotonous queue, the other elements in the queue d[k] is greater than d[front], so garbage I must be from the first element of the team to transport)
Then if the current calculated d[i] is less than the last element of the queue, it is necessary to discard larger or equal elements than d[i], if larger than d[i], then the garbage behind the transport, obviously from I start more than a few garbage start better.
If it is equal, then starting from I will not be worse than a few starting from the front, because I to the back of an element of weight and smaller, if the garbage in front of I, the value of D and I, perhaps the garbage to the back of some garbage weight and beyond C, will not get the optimal solution.
So is the maintenance interval weight and less than equal to C, if not satisfied, the head pointer + +, if the resulting solution is smaller than the last element of the queue, then plug into a smaller element than it, and larger than the discard.
#include <iostream> #include <cstdio> #include <cctype> #include <cstdlib> #include <cmath > #include <algorithm> #include <cstring> #include <string> #include <vector> #include <
queue> #include <map> #include <set> #include <sstream> #include <stack> using namespace std;
#define MAX 100005 typedef long Long LL;
const double pi=3.141592653589793;
const int INF=1E9;
const double INF=1E20;
const double eps=1e-6;
int X[max],y[max];
int total[max];//record the distance from 1-i int origin[max];//record in order from the origin point to i the distance int w[max];//record The weight of the former I garbage int c,n; The Int d[max];//Record collects the first I garbage after the shortest distance taken back after the int q[max];//sliding window monotone queue, optimized queue int func (int i) {return d[i]+origin[i+1]-total[i+1];} in
T main () {int t,p;
cin>>t;
while (t--) {scanf ("%d%d", &c,&n);
x[0]=y[0]=w[0]=total[0]=origin[0]=0;
for (int i=1;i<=n;i++) {scanf ("%d%d%d", &x[i],&y[i],&p);
W[i]=w[i-1]+p;
Total[i]=total[i-1]+fabs (X[i]-x[i-1]) +fabs (y[i]-y[i-1]); Origin[i]=fabs (X[i]) +fabs (Y[i]);
} int front=0,last=0;
q[front]=0;
for (int i=1;i<=n;i++) {while (front<=last&&w[i]-w[q[front]]>c) front++;
D[i]=func (Q[front]) +total[i]+origin[i];
while (Front<=last&&func (i) <=func (q[last)) last--;
Q[++last]=i;
} printf ("%d\n", D[n]);
if (t>0) printf ("\ n");
} return 0;
}