The subject is a topic of slope optimization using CDQ
Slope optimization before doing a few questions are the slope is monotonous, and the insertion point because the point in a certain dimension is monotonous, so only the operation of the team head and the end of the team can be completed optimization
But it's obviously not.
The main reference is two things
On the application of a kind of divide-and-conquer algorithm from "Cash"
(Day1) CDQ Division-related
These two directly on Baidu Search, the first out of IS
The test instructions of the subject is
A company acquired a plant n (10^5) days of Use
and a starting capital C (10^9), ready to lease machine production in n days to gain revenue
Machines can be rented with M (10^5), each machine has four values, D,p,r,g (D<=n, p,r,g are 10^9)
Show that you can spend p on D-day (there must be so much money in your hands first)
Lease this machine, starting from d+1 days the machine generates g of revenue every day, when you don't need a machine
Can sell this machine and get r money at a time
It is important to note that:
Only one machine can stay in the factory.
The day the machine can no longer be bought and sold, but one machine could be sold on the same date.
On the first day of n+1, you must sell the machine in hand.
Ask N+1 to get the most money
According to this test instructions
We can get a DP transfer equation.
The first thing to think about is whether there's a field to put the machine
This is certainly not the case at the very beginning, for fear of buying a pit machine is likely to lose money, but suppose you buy a good machine, you must have been running until the next machine came in.
And then we have to disperse all the time, which is the d of every machine.
Then use F[i] to show how much money is sold in the hands of the machine at the moment of D[i.
F[i] = max (f[i-1], f[j]-p[j] + r[j] + g[j] * (D[i]-d[j]-1))
where F[j] >= p[j]
You can see it's O (n^2), obviously not.
Make h[j] = F[j] + r[j]-p[j]-g[j] * (D[j] + 1)
The formula becomes f[i] = H[j] + d[i] * G[j]
ie h[j] =-d[i] * G[j] + f[i]
For this, it can be abstracted into a two-dimensional space.
by (G[j],h[j]) as the point set,-d[i] is the slope
Then the one that makes the biggest intercept is F[i] max.
Observe these point sets
Can be found, not a bit monotonous ah, you need to follow the g[j] This dimension to do a sort of
Made him monotonous at least in one dimension, to make it easy for us to do insert and delete operations
Then because the slope is monotonically decreasing and is negative
Can draw a picture, the last to maintain the most advantageous point set, on the figure is formed by a convex line
And then each point is to maintain the graph.
And then this sort of you in the normal DP method must not be sorted every time
It's going to take CDQ.
For an interval l,r
You first updated the L,mid
Then the point set of the section on the left side is sorted to form the graph above
And then update the right interval,
As the slope is decremented, you can see that we just need to sweep through the graph to update all the right interval values.
And then just recursively update it.
Complete CDQ Division
Overall complexity, it should be nlognlogn.
Because this sort is in every sub-range
The code is also referred to Xiaodao, because it is not familiar with this method.
It should be noted that when comparing the slopes, if you compare them by multiplication, they will overflow long long.
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include < cstdlib> #include <ctime> #include <set> #include <vector> #include <map> #define MAXN 11111# Define MAXM 55555#define INF 1000000007using namespace Std;long long f[111111];struct node {int d, p, G, r;} P[111111];bool CMP (node x, node Y) {return x.d < Y.D;} int N, d;typedef pair<int, long long> pa;pa a[111111], C[111111];long long h (Int j) {return f[j] + (long long) p[ J].R-(long Long) P[J].P-(Long Long) P[J].G * (Long Long) (P[J].D + 1);} int Slopecomp (PA A, PA B, PA c) {Long long xa = b.first-a.first; Long long xb = C.first-a.first; Long Long ya = B.second-a.second; Long Long YB = C.second-a.second; Double tmp = (double) xa * YB-(double) xb * YA; return tmp < 0;} void Cdq (int l, int r) {if (L + 1 < r) {int m = (L + r) >> 1; CDQ (L, M); int na = 0, NB = 0, NC = 0; For (inT j = l; J < M; J + +) {if (F[j] >= p[j].p) a[na++] = PA (P[J].G, H (j)); } sort (A, A + NA); for (int i = 0; i < na; i++) {while (NC > 1 &&!slopecomp (c[nc-1], C[NC], a[i])) nc--; C[++NC] = A[i]; } int j = 0; for (int i = m; i < R; i++) {Long Long A1, A2, B1, B2, X; x = P[I].D; while (J < NC) {a1 = C[j].first; A2 = C[j + 1].first; B1 = C[j].second; b2 = c[j + 1].second; if (A1 * x + b1 >= A2 * x + b2) break; j + +; } F[i] = max (F[i], (Long Long) C[j].first * x + c[j].second); } CDQ (M, R); }}int Main () {int cas = 0; while (scanf ("%d%i64d%d", &n, &f[0], &d)! = EOF) {if (n = = 0 && f[0] = = 0 && D = = 0) bre Ak for (int i = 1; I <= n; i++) scanf ("%d%d%d%d", &p[i].d, &P[I].P, &P[I].R, &P[I].G); Sort (p + 1, p + N + 1, CMP); ++n; P[N].D = d + 1; P[N].G = P[N].P = 0; for (int i = 1; I <= n; i++) f[i] = f[0]; CDQ (0, n + 1); printf ("Case%d:%i64d\n", ++cas, F[n]); } return 0;}
Slope optimization of HDU 3842 machine Works CDQ