Bzoj 1492 NOI 2007 Currency Exchange Cash CDQ Division + slope optimization DP

Source: Internet
Author: User

There are two kinds of gold coupons, A and B. Each day there is a rate value, which indicates the proportion of the purchase, and the price of the AB Gold coupon every day. Now give the initial amount of money and ask how much you can get at the end.


Idea: This is a divine problem, chewing the paper to chew someone else code for almost a day to calculate a little understand.

First of all, you can buy a part of the title or sell a part of it is nonsense, because in order to maximize profits must buy all, sell all. The naïve DP equation is good.

F[i] is the maximum number of B coupons for the first day. Then f[i] = (rate[j] * f[j] * A[i] + f[j] * B[i])/(Rate[i] * A[i] + b[i])

Tidy up and set x[j] = rate[j] * F[j]/(rate[i] * A[i] + b[i])

Y[J] = f[j]/(rate[i] * A[i] + b[i])

Then f[i] = a[i] * X[i] + b[i] * Y[i]

This can be solved by applying slope optimization. But XY is not monotonous, so can not be maintained with a monotonous queue, need to maintain a convex shell with splay. Think of yesterday do dynamic maintenance convex bag, use set to get all disgusting half a day, this directly on splay maintenance convex shell or forget, obediently gnawing paper on CDQ bar.

For the first time, CDQ was led to the question by God Ben. In short, it is probably summed up a bit, CDQ the basic steps of division.

1. When recursion is in the end, process the answer directly and then return.

2. Make a mid

3. Recursive solution [L,mid]

4. Handling [L,mid] 's impact on [mid + 1,r] (important

5. Recursive resolution [Mid + 1,r]

6. Merge [L,mid] and [mid + 1,r] to prepare for the impact between the next processing interval.

In addition, the base time complexity of CDQ Division is O (NLOGN), usually in the middle of what to multiply what. Generally, tree-like arrays are commonly used, i.e. O (nlog^2n).

It is possible to use CDQ to avoid complex data structures such as tree sets and trees to ensure ample time in the examination room. (CDQ Tree Set Tree (O (nlog^3n)))

For the subject, we need to deal with the points on the convex hull in the CDQ division. Each time to deal with the left interval on the right interval of the time, the first to follow the question of the time to simple separation of the left, at least to ensure that there is no tj>ti,j update I situation. Then the left update to the right of the situation is completely legal.

After the separation, the two sides of the query is ranked according to the slope, so use the stack to maintain the convex hull on the left, and then use this convex package to update the right side of the F value of the point, these are O (n).

The final merge, or O (n). The total time complexity is O (Nlogn), very good time complexity and code complexity.


CODE (did not write splay maintenance convex shell, dare not write ... )

(If the code of this Konjac Konjac is somewhat similar to the code of Hzwer Ben, please do not take offense, because I am the one who took it ... ):


#include <cstdio> #include <iomanip> #include <cstring> #include <iostream> #include < Algorithm> #define Max 100010using namespace std; #define MAX (b) ((a) > (a):(b) struct ask{double a,b,rate,k;int pos;double x,y;bool operator < (const ASK &a) const {return k > a.k;} void Read (int p) {scanf ("%lf%lf%lf", &a,&b,&rate); k =-a/b;pos = P;}} Ask[max],t[max];int cnt;double f[max];inline Double getslope (Ask *a,ask *b) {if (b = = &ask[0]) return-1e20;if (a->x = = b->x) return 1e20;return (a->y-b->y)/(a->x-b->x);}  void CDQ (int l,int r) {if (L = = r) {F[l] = max (f[l],f[l-1]); ask[l].y = F[l]/(ASK[L].A * ask[l].rate + ask[l].b); ask[l].x = Ask[l].rate * Ask[l].y;return;} int mid = (L + r) >> 1;int L1 = L,l2 = mid + 1;for (int i = l; I <= R; ++i) if (Ask[i].pos <= mid) t[l1++] = Ask[i ];elset[l2++] = ask[i];for (int i = l; I <= R; ++i) Ask[i] = T[i]; CDQ (l,mid); static Ask *stack[max];int top = 0;for (int i = l; I <= Mid ++i) {while (Top > 1 && getslope (Stack[top-1],stack[top]) <= Getslope (Stack[top-1],&ask[i]))--top;st Ack[++top] = &ask[i];} Stack[++top] = &ask[0];int now = 1;for (int i = mid + 1, I <= R; ++i) {while (now < top && Getslope (stack[ Now],stack[now + 1]) >= ask[i].k) ++now;f[ask[i].pos] = max (f[ask[i].pos],stack[now]->x * ask[i].a + stack[now]- >y * ask[i].b);} CDQ (mid + 1,r); L1 = L,l2 = mid + 1;for (int i = l; I <= R; ++i) if (((ask[l1].x < ask[l2].x | | (ask[l1].x = = ask[l2].x && ask[l1].y < ASK[L2].Y)) || L2 > R) && L1 <= mid) t[i] = Ask[l1++];elset[i] = ask[l2++];for (int i = l; I <= R; ++i) Ask[i] = T[i];} int main () {cin >> cnt >> f[0];for (int i = 1; I <= cnt; ++i) Ask[i]. Read (i); sort (ask + 1,ask + cnt + 1); CDQ (1,cnt) cout << fixed << setprecision (3) << f[cnt] << endl;return 0;}


Bzoj 1492 NOI 2007 Currency Exchange Cash CDQ Division + slope optimization DP

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.