Question link ~~>
Question recognition:This is the first question of the monotonous queue. I finally understood it and combined it with white books and various online materials.
Solution: monotonous queue DP
The focus of this question is on changing the dynamic transfer equation. First, we set dp [I] to the minimum distance used to process the I garbage, so it is easy to think of the dynamic transfer equation: dp [I] = min {dp [j] + d (j + 1) + d (j + 1, I) + d (I)} and w (j + 1, i) <= W, meaning: d (I) is the distance from the point I to the origin (the Hamilton distance), d (j + 1, I) represents the distance from j + 1 to I. W (j + 1, I) is the weight and from j + 1 to I. W is the maximum weight.
Well, the next step is how to convert the dynamic equation: We use the prefix and the idea to record the prefix distance and the prefix weight respectively, respectively using the array sumd [I], sumw [I], d [I] is the distance from vertex I to the origin, so that the equation can be changed:
Dp [I] = min {dp [j] + d [j + 1] + sumd [I]-sumd [j + 1] + d [I]} and sumw [I ]-sum [j] <= W;
Further transformation ==>
Dp [I] = min {dp [j] + d [j + 1]-sumd [j + 1]} + sumd [I] + d [I]; in this case, you will find that the preceding numbers are only related to themselves. You can put them in a queue, as long as you maintain the minimum value of the queue (when the weight is satisfied ), then the time for calculating dp [I] is changed to O (1.
For details, see the code:
# Include <iostream> # include <sstream> # include <map> # include <cmath> # include <fstream> # include <queue> # include <vector> # include <sstream> # include <cstring> # include <cstdio> # include <stack> # include <bitset> # include <ctime> # include <string> # include <cctype> # include <iomanip> # include <algorithm> using namespace std; # define INT long int # define L (x) (x * 2) # define R (x) (x * 2 + 1) const int INF = 0x3f3f3f; const double esp = 0.0000000001; const double PI = acos (-1.0); const int mod = 1000000007; const int MY = (1 <5) + 5; const int MX = 100010 + 5; int n, W; int sumw [MX], d [MX], dp [MX], deq [MX], sumd [MX]; int Cavalue (int j) {return dp [j] + d [j + 1]-sumd [j + 1];} void input () {int x, y, w; scanf ("% d", & W, & n); sumw [0] = sumd [0] = d [0] = 0; int x1 = 0, y1 = 0; for (int I = 1; I <= n; ++ I) {scanf ("% d", & x, & y, & w); sumw [I] = sumw [i-1] + w; // Weight prefix and d [I] = abs (x) + abs (y ); // the distance to the origin sumd [I] = sumd [i-1] + abs (x-x1) + abs (y-y1); // The distance prefix and x1 = x; y1 = y ;}} void DP () {memset (deq, 0, sizeof (deq); int front = 0, end = 0; // head and end of the deq double-end queue for (int I = 1; I <= n; ++ I) {while (front <end & Cavalue (deq [end-1])> = Cavalue (i-1) end --; deq [end ++] = i-1; while (front <end & sumw [I]-sumw [deq [front]> W) front ++; dp [I] = Cavalue (deq [front]) + d [I] + sumd [I] ;}} int main () {int Tx; scanf ("% d", & Tx); while (Tx --) {input (); DP (); cout <dp [n] <endl; if (Tx) cout <endl;} return 0 ;}
UVALive 3983 Robotruck (monotonous queue)