"Bzoj" 1492: [NOI2007] Currency exchange cash (CDQ division)

Source: Internet
Author: User

http://www.lydsy.com/JudgeOnline/problem.php?id=1492

Konjac Konjac to learn CDQ God algorithm ah.

See article Chen Danqi "Cash" on the application of a class of divide and conquer algorithm

Orz

This question represents the precision of being pits ..... Cause no 1a ... I have a few rounds in the trumpet .......... Keng.

Konjac Konjac talk about your own understanding of it.

First of all, this god DP ... (indicates that it is completely invisible)

First of all we want to maximize the money, then you can convert the problem to maximize a coupon! (or b coupon)!!! This is too divine, be sure to remember these!!

Set D[i] I can get the first day of RMB all buy a coupons and b coupons (if the remaining A and B coupons sold before buying, I do not know why Qaq, and then Baidu, it seems to be said, the first to maximize the money (ie all converted into money), and then buy a and B coupons. For what? ), there

d[1]=s*rate[1]/(A[1]*rate[1]+b[1]), for what, you solve the equation a*a[1]+b*b[1]=s, a/b=rate[1] ....

d[i]=max{d[j]*a[i]+d[j]/rate[j]*b[i]}*rate[i]/(A[i]*rate[i]+b[i]), the front that Max is the maximum amount of RMB that can be obtained at this time, that is, from the start of J days to stay until the first day.

And then obviously this is $o (n^2) $ ...

Let's assume that the decision Monotonicity (now DP has been extended to arbitrary assumptions and then arbitrarily maintained the embarrassment ...). Too god Orz. It seems that 1d1d should be fully optimized to $o (NLOGN) $ and below.)

Suppose the decision J and K, have $d[j]<d[k]$ and decision J better than K, you see, are all hypothetical! (The lowered rate is written as R)

Then there are:

$ $d [j] \times A[i]+d[j]/r[j] \times b[i]>d[k] \times a[i]+d[k]/r[k] \times b[i]$$

A little bit of simplification can get

$$ (D[j]/r[j]-d[k]/r[k])/(D[j]-d[k]) <-a[i]/b[i]$$

Set $g[i]=d[i]/r[i]$, then get:

$$ (G[j]-g[k])/(D[j]-d[k]) <-a[i]/b[i]$$

Then can get, when

$$ (G[j]-g[k])/(D[j]-d[k]) <-a[i]/b[i] and d[j]<d[k]$$

, decision J is better than decision K

What good is it? Obviously we are building a balance tree that maintains the convex line (the keyword is $d[i]$), and then we find the optimal value in two points. But you are willing to fight the balance tree ....

So CDQ god Ben introduced the CDQ division, Orz

We think of all the dots as $ (d[i], G[i]) $, we want to, suppose that for the decision I~n, all the J in front of me has been begged, I'm not going to be able to sort the $d[j]$ and then maintain the slope of the convex line in the monotone $i~n$ then you can $o (n) $ update value. This can refer to the 1D1D quadrilateral optimization of the monotone stack update the subsequent state of the paper.

So we define the operation $solve (L, R) $ to indicate that the D value of $l~mid$ has been updated, and then it is sorted with these points to maintain the convex line and then update $mid+1~n$ these values.

Wow, what a magical look! If it can be done in $solve (L, R) $ with $o (n) $, then the complexity is $o (NLOGN) $!

So CDQ god Ben is made out Orz

First we analyze the assumption that the value of $l~mid$ is updated, and what kind of convex line is maintained? If you follow my above deduction, then the answer is a convex hull.

Why is it? Because for the decision-making i,j than K, at this time the left-less right operand style, our goal is to find the first large less right operand-type K to update the answer, so we maintain a slope increment convex hull. Hence the upper convex hull. The right-hand side is obviously also to maintain the monocytogenes, because for the decision J and K, if J is better than K, then for the larger slope, will not use K.

The upper convex hull always ...

Then consider CDQ Division.

We need to implement:

$O (n) $ implement $l~mid$ maintenance out $d[i]$ monotone

$O (n) $ implement $mid+1~n$ maintenance out $-a[i]/b[i]$ monotone

And because it is divided, for the first situation, we should naturally think of the merger sort, then complete.

For the second case, we can preprocess all the $-a[i]/b[i]$ of the $1~n$ and then remove the >mid point when the partition is taken.

Then finish ~ Sprinkle flowers

So how do you think about the answer? The answer is to maintain an array of maximum RMB f,f[i] to indicate the maximum amount of money I get in the first day, then the transfer was said before ....

So when the division is $l==r$, we need to consider updating $f[l]$ and update all the information about $l$, which is $g[l]$.

Initialize $f[0]=s$, so we $l==r$ when we have to join $f[l]=max (F[L-1], f[l]) $ ...

Also note that maintaining the convex line must be aware of inserting the coordinate system vertices, i.e. (0,0)

So look at the code.

#include <cstdio> #include <cstring> #include <cmath> #include <string> #include <iostream > #include <algorithm> #include <queue> #include <set> #include <map>using namespace std; typedef long Long LL; #define REP (i, n) for (int i=0; i< (n); ++i) #define FOR1 (i,a,n) for (int i= (a); i<= (n); ++i) #define For2 (i,a,n) for (int i= (a);i< (n), ++i) #define FOR3 (i,a,n) for (int i= (a); i>= (n); i.) #define FOR4 (i,a,n) for (int i= ( a);i> (n); i) #define CC (i,a) memset (i,a,sizeof (i)) #define READ (a) a=getint () #define PRINT (a) printf ("%d", a) # Define DBG (x) cout << (#x) << "=" << (x) << endl#define error (x) (! x) puts ("error"): 0) #define RDM (x, i) for (int i=ihead[x]; i; i=e[i].next) inline const int Getint () {int r=0, k=1; Char c=g Etchar (); for (; c< ' 0 ' | | C> ' 9 '; C=getchar ()) if (c== '-') k=-1; for (; c>= ' 0 ' &&c<= ' 9 '; C=getchar ()) r=r*10+c-' 0 '; return k*r; }const int N=100005;const double eps=1e-8;struct dat {double x, y, R, A, B, K; int id; }t[n], P[N];CONST BOOL cmp (const DAT &a, const dat &b) {return a.k<b.k;} Double F[n];int N, S[n];inline const double GETK (const int &AMP;J, const int &k) {return (P[J].Y-P[K].Y)/(P[j].x-p[k] . x); }inline void fix (const int &i, const int &j) {F[p[i].id]=max (f[p[i].id], p[j].x*p[i].a+p[j].y*p[i].b);} void Cdq (int l, int r) {if (l==r) {F[l]=max (f[l], f[l-1]);p [l].x=f[l]*p[l].r/(p[l].a*p[l].r+p[l].b);p [L].y=p[l].x/p[l] . R;return;} int mid= (L+R) >>1, l1=l, L2=mid+1;for1 (i, L, R) if (P[i].id<=mid) t[l1++]=p[i]; else T[l2++]=p[i];for1 (i, L, R) P[I]=T[I];CDQ (L, mid), int top=0;s[++top]=0;for1 (I, L, mid) {while (top>1 && get K (S[top], s[top-1]) <getk (s[top-1], i) +eps)--top; The EPS here is disgusting. S[++top]=i;} For1 (i, mid+1, R) {while (top>1 && getk (S[top], s[top-1]) +eps<p[i].k (i,--top;fix]);} CDQ (mid+1, R); L1=l, L2=mid+1;top=l;while (top<=r) if (L1<=mid && (l2>r | | p[l1].x<p[l2].x)) t[top++] =p[l1++];else T[Top++]=p[l2++];for1 (I, L, R) P[i]=t[i];} int main () {read (n); Read (f[0]); For1 (i, 1, n) {scanf ("%lf%lf%lf", &p[i].a, &p[i].b, &AMP;P[I].R);p [I].id=i;p[i] . k=-p[i].a/p[i].b;} Sort (p+1, p+1+n, CMP), CDQ (1, N);p rintf ("%.3f", F[n]); return 0;}

  

Descriptioninput the first row of two positive integers n, S, respectively, indicating the number of days the small Y can predict and the initial amount of money. Next n lines, the K line three real AK, BK, Ratek, meaning as described in the title output has only a real maxprofit, indicating the maximum amount of money that can be obtained at the end of the nth day operation. The answer retains 3 decimal places. Sample INPUT3 100
1 1 1
1 2 2
2 2 3Sample Output225.000hint



The test data is designed so that the accuracy error does not exceed 10-7.
For 40% of test data, meet n≤10;
For 60% of test data, meet N≤1 000;
For 100% of test data, meet N≤100 000;

Source

"Bzoj" 1492: [NOI2007] Currency exchange cash (CDQ division)

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.