CDQ divide and conquer, DP. This problem is too difficult, I have seen a little clue in the morning//Konjac Konjac Nature
Even this is done while writing, or Forget (fog).
The upper convex package is maintained.
2.30 pm finally over, according to People's solving the puzzle, incredibly have been handed over more than 10 times. Konjac Konjac Nature
First of all, it is not difficult to get the conclusion that if the Buy will be all the money to use up (buy can make money, you need to buy more, than other money to buy other). If they sell, they'll sell them.
Save A[i],b[i],rate[i with Array a].
Use f[i].x to represent the maximum number of items that can be bought on the X day, F[I].Y represents the largest B item. Then there is f[i].x = F[I].Y*A[I].R.
Use V[i] for the first day to get the maximum benefit , then v[i] = max (V[i]-1,f[i].x*a[i]+f[i].y*b[i]).
Violent enumeration O (n^2), tle.
Therefore, a convex hull must be maintained.
On the first day, suppose f[j].x<=f[k].x, if the decision J is better than K, there is (f[i].x-f[j].x) *a[i].a+ (F[J].Y-F[K].Y) *a[i].b>0.
After the move, there is (F[J].Y-F[J].Y)/(f[j].x-f[j].x) <–a[i].a/a[i].b.
Remember this conclusion first, then use it?
1. Sort by (-a[i]/b[i]) in descending order when preprocessing.
2/Then rely on the balance tree (I won't.) ) and CDQ (I copied the. The
CDQ Division: First of all, the interval to be processed into two parts, first recursive processing left interval, and then calculate the right interval , the last recursive processing right interval.
What good is this? This is when you calculate the DP value for a day, and it also handles part of the DP value for all the days that follow.
Why is it? If we sort by monotonic, we maintain a lower convex hull.
In the case of J, it is assumed that the K-day is the optimal decision, so that the values before K days are useless in the decision after the first J days.
Because the satisfaction is less than –a[j].a/a[j].b, it must be less than –a[h].a/a[h].b,h>j. Because the sort was over.
Divide and conquer altogether logn layer, each layer traverse n number, total complexity O (NLOGN).
#include <cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespacestd;Const intMAXN =100000+Ten;intN,M,P[MAXN],S[MAXN];structPoint {Doublex, y;} F[MAXN],T[MAXN];structDay {DoubleA,b,r;} A[MAXN];DoubleV[MAXN];BOOL operator<(Point A,point b) {returna.x < b.x | | (a.x==b.x&&a.y<b.y);}BOOLcmpintXinty) {returnA[X].B/A[X].A > a[y].b/a[y].a;}BOOLdir (Point a,point b,point c) {return((b.x-a.x) * (C.Y-B.Y)-(B.Y-A.Y) * (c.x-b.x)) >=0;}DoubleCalc (Point F,inti) {returnF.X*A[I].A + f.y*a[i].b;}voidCdqintLintRDoublem) {if(L = =R) {V[l]=Max (v[l],m); F[l].y= v[l]/(a[l].a*a[l].r+a[l].b); f[l].x= a[l].r*f[l].y; return; } intMid = (l+r)/2, m1=l,m2=mid+1, l=0, r=0; for(inti=l;i<=r;i++) { if(P[i]<=mid) s[m1++]=P[i]; Elses[m2++]=Q[i]; } memcpy (P+l,s+l,sizeof(int) * (r-l+1)); CDQ (L,MID,M); for (inti=l;i<=mid;i++) { while(r>1&& Dir (t[r-2],t[r-1],f[i]) r--; T[r++] =F[i]; } for(intI=mid+1; i<=r;i++) { while(l<r-1&& Calc (t[l],p[i]) <calc (t[l+1],p[i]) + +m; V[p[i]]=Max (V[p[i]],calc (t[l],p[i)); } CDQ (Mid+1, R,v[mid]); Merge (f+l,f+mid+1, f+mid+1, f+r+1, T); memcpy (f+l,t,sizeof(point) * (r-l+1));}intMain () {scanf ("%d%d",&n,&m); for(intI=1; i<=n;i++) {scanf ("%LF%LF%LF",&a[i].a,&a[i].b,&A[I].R); P[i]=i; } sort (P+1, p+n+1, CMP); CDQ (1, n,m); printf ("%.3lf\n", V[n]); return 0;}
bzoj1492: [NOI2007] Currency exchange cash