1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6 #defineMAXN 1000057 #defineINF 10000000008 using namespacestd;9 Ten Const Doubleinf=1e- -; One intN,G[MAXN],HEAD,TAIL,LIST[MAXN]; A DoubleANS,ST,F[MAXN],A[MAXN],B[MAXN],RI[MAXN]; - structdate{ - Doublea,b,r,k; the intID; - }cash[maxn],temp[maxn],p; - structnote{ - Doublex, y; + intID; - }point[maxn],tmp[maxn],pp; + A BOOLComp (date x,date y) { at returnX.k>Y.K; - } - - DoubleGETK (intXinty) { - if(!y)return-Inf; - if(point[x].x==point[y].x)returnInf; in return(POINT[X].Y-POINT[Y].Y)/(point[x].x-point[y].x); - } to + voidSolveintLintR) { - if(l==R) { theAns=max (ans,f[g[l]]* (a[l]+b[l]/ri[g[l])); *f[l]= (Ri[l]*ans)/(a[l]*ri[l]+b[l]); $Point[l].x=f[l],point[l].y=f[l]/ri[l],point[l].id=l;Panax Notoginseng return; - } the intMid= (L+R)/2; + for(intI=l,j=mid+1, k=l;k<=r;k++){ A if(Cash[k].id<=mid) temp[i++]=Cash[k]; the Elsetemp[j++]=Cash[k]; + } - for(inti=l;i<=r;i++) cash[i]=Temp[i]; $ solve (l,mid); $Head=1, tail=0; - for(inti=l;i<=mid;i++){ - while(HEAD<TAIL&&GETK (List[tail],i) >GETK (list[tail],list[tail-1]) +inf) tail--; thelist[++tail]=i; - }Wuyi for(intI=mid+1; i<=r;i++){ thep=Cash[i]; - while(HEAD<TAIL&&GETK (list[head],list[head+1]) >p.k+inf) head++; Wupp=Point[list[head]]; - if((P.a*pp.x+p.b*pp.y>p.a*f[g[p.id]]+p.b*f[g[p.id]]/ri[g[p.id]]+inf) | |! G[p.id]) g[p.id]=pp.id; About } $Solve (mid+1, R); - for(intI=l,j=mid+1, k=l;i<=mid| | j<=R;) { - if(j>r| | (i<=mid&&point[i].x<point[j].x)) tmp[k++]=point[i++]; - Elsetmp[k++]=point[j++]; A } + for(inti=l;i<=r;i++) point[i]=Tmp[i]; the } - $ intMain () { theMemset (G,0,sizeof(g)); thescanf"%D%LF", &n,&st), ans=St; the for(intI=1; i<=n;i++){ thescanf"%LF%LF%LF", &CASH[I].A,&CASH[I].B,&CASH[I].R), cash[i].id=i; -a[i]=cash[i].a,b[i]=cash[i].b,ri[i]=CASH[I].R; incash[i].k=-cash[i].a/cash[i].b; the } the //for (int i=1;i<=n;i++) printf ("%.3lf\n", CASH[I].K); AboutSort (cash+1, cash+n+1, comp); the //for (int i=1;i<=n;i++) printf ("%d%lf\n", CASH[I].ID,CASH[I].K); theSolve1, n); theprintf"%.3lf\n", ans); + //for (int i=1;i<=n;i++) printf ("%d\n", G[i]); - //for (int i=1;i<=n;i++) printf ("%.3lf\n", F[i]); the return 0;Bayi}
View Code
Title Link: http://www.lydsy.com/JudgeOnline/problem.php?id=1492
Small y recently worked on a Gold exchange. The Gold Exchange only issues two types of gold coupons: A commemorative voucher (hereinafter referred to as a coupon) and a B commemorative voucher (the following
B voucher). Each customer who holds a gold coupon has an account of his own. The number of gold coupons can be a real. With the fluctuation of the market every day, both kinds of gold coupons have their own value at that time, that is, the number of RMB that can be exchanged on the day of each unit gold coupon. We recorded the value of a and B coupons in K days respectively as AK and BK (Yuan/Unit gold coupon). For the convenience of customers, the Gold Exchange provides a very convenient way to trade: proportional Trading method. The proportional trading method is divided into two areas: (a) selling a gold coupon: The customer provides a real OP in [0,100] as a sell ratio, meaning: The op% 's a coupon and the B-coupon of op% are converted to renminbi at the current value; (b) Buy Gold coupon: Customers pay IP yuan, the exchange will be redeemed to the user's total price The value is the gold coupon of the IP, and the proportion of the A and B coupons that are provided to the customer happens to be Ratek on the K-day; For example, assume that the change of Ak, Bk, and Ratek in the next 3 days are: Assuming that on the first day, the user has 100 yuan but no gold coupon. The user can do the following: Notice that multiple operations can be performed within the same day. Small y is a very economic-minded staff, through a long period of operation and market estimates, he has been aware of the next n days of the value of a and B coupons and rate. He also wanted to be able to figure out how much it would take for n days to start with S-Dollars. Sample input: Enter the first line 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 numbers AK, BK, Ratek, meaning as described in the topic. For 100% of test data, meet: 0<ak≤10;0<bk≤10;0<ratek≤100;maxprofit≤10^9,n<=1*10^5. "Tip" 1. The input file may be large, please use a fast read-in mode. 2. There must be an optimal buying and selling solution: use all RMB for each purchase operation, and sell all Gold coupons for each sell operation. Sample output:
There is only one real maxprofit, which represents the maximum amount of money that can be obtained at the end of the nth day operation. The answer retains 3 decimal places.
Practice: At the beginning of this problem, think carefully about the nature of the problem, we found that the best solution must be every buy operation to use all the renminbi, each sell operation to sell all the gold coupons, so N^2DP is very easy to think of, we set F[i] for the first day of the most remaining a gold coupon number, Ans represents the most current renminbi, the state transition equation is:
1#include <iostream>2#include <cstdio>3#include <cstring>4#include <algorithm>5#include <cmath>6 #defineMAXN 1000057 using namespacestd;8 9 intN;Ten DoubleANS,S,F[MAXN],A[MAXN],B[MAXN],R[MAXN]; One A intMain () { - Doublex; -scanf"%D%LF", &n,&s), ans=s; the for(intI=1; i<=n;i++) scanf ("%LF%LF%LF",&a[i],&b[i],&r[i]); -f[1]= (r[1]*ans)/(a[1]*r[1]+b[1]); - for(intI=2; i<=n;i++){ - for(intj=1; j<=i-1; j + +){ +Ans=max (ans,a[i]*f[j]+b[i]*f[j]/r[j]); - } +f[i]= (R[i]*ans)/(r[i]*a[i]+b[i]); A } atprintf"%.3lf\n", ans); - return 0; -}
View Code
We set j,k to two decisions for I, J-ratio K-superior when and only if: ai*fj+bi*fj/rj>ai*fk+bi*fk/rk, simplification can be: (FJ/RJ-FK/RK)/(FJ-FK) <-ai/bi, set Gi=fi/ri, set fj< FK, so (GJ-GK)/(FJ-FK) <-ai/bi, we can maintain a convex line,-ai/bi can be preprocessed, fi and GI is in the process of CDQ division can be obtained, through this we can find each I optimal decision.
In fact, there are two ways, a balance tree maintenance convex line, this kind of a more disgusting, later to fill the pit bar, the second is CDQ division, I use CDQ division, we define the solve (L,R) process, after the implementation of the process, we can get f[l~r], our goal is solve (1, N).
The CDQ division process is as follows:
You can pre-preprocess an array-ai/bi to ensure a monotonic descent.
Solve (l,r) {
First guarantee the order, O (n) sweep once, the concrete visible code.
Solve (L,mid), L~mid This section of the F-value has been calculated, according to the F-value from small to large order.
L~mid This section of the establishment of the convex line, mid+1~r on the convex line to update the optimal decision can be (because it is monotonous, for the second interval, we only need to find the first line of the slope of the small with its-a/b can be, this process with two hands sweep once).
Solve (MID+1,R);
Each of the two intervals has been calculated and monotonically increasing, and the merge ordering ensures that the whole L~RF value is monotonically increasing for the benefit of future generations.
}
This is the whole process of CDQ Division, code implementation is more disgusting, see the code.
Nausea CDQ Division + slope optimization, wrote for four or five days.
CDQ Division + Slope Optimization.
bzoj1492: [NOI2007] Currency exchange cash