1492: [NOI2007] Currency exchange cash time limit: 5 Sec Memory Limit: MB
Submit: 1948 Solved: 879
[Submit] [Status] [Discuss] 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;
dp+ slope optimization +cdq divide and conquer.
F[i] represents the maximum profit after the first day of the day.
F[i]=max (F[I-1],XJ*AI+YJ*BI)
Xj,yj said that the maximum profit of J Day F[j] to buy a commemorative voucher, can buy the number of a and B coupons.
Set P=xj*ai+yj*bi
So Yj=-ai/bi*xj+p/bi
To see (XJ,YJ) as a point, p is the intercept, is to let a slope of-ai/bi line from the infinity of the place to translate downward, the first hit point (Xj,yj) is the point that makes the answer optimal.
It can be found that the optimal point is on the upper convex hull formed by the previous (XJ,YJ) point, and the slope is the optimal left point of the successor edge of the-ai/bi.
Obviously can use the splay to maintain, but CDQ divide the rule to write much better.
Sort the slope in descending order, after the recursion is resolved (l,mid), the effect of the calculation (L,mid) on (mid+1,r):
The point of (L,mid) is built on the convex hull, because (mid+1,r) is sorted in descending order of slope, so the (MID+1,R) can be updated all at once by sweeping the convex hull.
Note that after the recursive calculation (MID+1,R), you want to sort by x in ascending order, because the current (L,R) is all done, his usefulness is to build a convex hull.
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include < cstdlib> #include <cmath> #define EPS 1e-9#define M 100005using namespace std;double f[m];int n,s[m];struct data{ Double x,y,a,b,k,rate;int ID;} P[m],q[m];bool CMP (data a,data b) {return A.K>B.K;} Double getk (int x,int y) {if (!y) return-1e20;if (Fabs (p[x].x-p[y].x) <eps) return 1e20;return (P[X].Y-P[Y].Y)/(P[x]. x-p[y].x);} void CDQ (int l,int r) {if (l==r) {F[l]=max (f[l],f[l-1]);p [l].y=f[l]/(p[l].a*p[l].rate+p[l].b);p [L].x=p[l].y*p[l]. Rate;return;} int l1=l,mid= (L+R) >>1,l2=mid+1;for (int i=l;i<=r;i++) if (p[i].id<=mid) q[l1++]=p[i]; else Q[l2++]=p[i]; for (int i=l;i<=r;i++) p[i]=q[i]; CDQ (l,mid); int top=0;for (int i=l;i<=mid;i++) {while (TOP>1&&GETK (S[top-1],s[top]) <EPS+GETK (S[top] , i)) top--;s[++top]=i;} S[++top]=0;int j=1;for (int i=mid+1;i<=r;i++) {while (J<TOP&&GETK (s[j],s[j+1]) +eps>p[i].k) j++;f[p[ I].id]=max (f[p[i].id],p[s[j]]. X*P[I].A+P[S[J]].Y*P[I].B);} CDQ (mid+1,r); l1=l,l2=mid+1;for (int i=l;i<=r;i++) if (p[l1].x<p[l2].x| | L2>R) &&l1<=mid) q[i]=p[l1++]; else q[i]=p[l2++];for (int i=l;i<=r;i++) p[i]=q[i];} int main () {scanf ("%d%lf", &n,&f[0]), for (int i=1;i<=n;i++) {scanf ("%lf%lf%lf", &p[i].a,&p[i].b, &p[i].rate);p [I].k=-p[i].a/p[i].b;p[i].id=i;} Sort (p+1,p+n+1,cmp); CDQ (1,n);p rintf ("%.3lf\n", F[n]); return 0;}
"Bzoj 1492" [NOI2007] Currency exchange cash