Chain of title:
http://www.lydsy.com/JudgeOnline/problem.php?id=3963
Exercises
slope optimization dp,cdq divide and conquer.
sort by time first. (Specify the time of sale of the machine D[i] greater than the i-1 machine's sell time d[i-1])
definition Dp[i] indicates the maximum benefit that can be obtained after the sale of all machines on the day on which the first machine could be traded (the final answer is dp[all_day+1])
Transfer clearly:
$DP [i]=dp[i-1]$
$DP [I]=max (dp[j]+ (d_i-d_j-1) *g_j-p_j+r_j) (J<i and Dp[j]>=p[j]) $
make $y_j=dp[j]-(d_j+1) *g_j-p_j+r_j$, if there are two transfer points k,j and G[k]<g[j], suppose J Point is better than K point
so $Y _j-y_k>-d_i (g_j-g_k) $
$\quad\quad\frac{y_j-y_k}{g_j-g_k}>-d_i$
then the conclusion is that if G[K]<G[J], and Slope (j,k) >-d[i], then the J-point is better than the K-point.
at the same time if there are three points of transfer origin: K,j,i, satisfying g[k]<g[j]<g[i],
at the same time Slope (i,j) >slope (J,k), the J point is invalid.
so for each source point two-tuple (g[j],y[j]), you only need to maintain a convex hull on the plane.
But G is not monotonous, so use CDQ to divide the treatment.
for each layer of the division of L~r, the first recursive processing left L~mid, and then the left by G from small to large sorting, and maintenance of the upper convex shell.
since D is monotonically increasing, it is good to traverse the convex hull and the right mid+1~r to contribute.
Code:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define MAXN 100050#define ll long longusing namespace Std;ll y[maxn],g[maxn],d[maxn],p[maxn],r[maxn],dp[maxn];int H[MAXN],N,C,T,S ; bool CMP (int I,int j) {return d[i]<d[j];} struct Moque{int q[maxn],l,r; #define Slope (I,j) (1.0* (Y[i]-y[j])/(g[i]-g[j]) void Reset () {l=1; r=0;} void Push (int i) {if (L<=r&&g[i]==g[q[r]]) {if (Y[i]>y[q[r]]) r--; else return;} while (L+1<=r&&slope (I,q[r]) >slope (q[r],q[r-1])) r--;q[++r]=i;} int Query (int i) {while (L+1<=r&&slope (Q[l+1],q[l]) >-d[i]) L++;return q[l];}} q;void Solve (int l,int r) {static int tmp[maxn],cl,cr,p; static ll Maxdp;if (L==R) return (void) (y[h[l]]=dp[h[l]]-(D[h[l]] +1) *g[h[l]]-p[h[l]]+r[h[l]); int mid= (L+R) >>1;solve (l,mid);//After, left G monotone Q.reset (); maxdp=0;for (int i=l;i<=mid;i++) {Maxdp=max (Maxdp,dp[h[i]]), if (Dp[h[i]]>=p[h[i]]) Q.push (h[i]);//The slope of the convex hull is reduced by a single}// Di monocytogenes,-di single minus, positive sequence enumeration is good. for (int i=mid+1,j;i<=r;i++) {j=q.query (H[i]);D P[h[i]]=max (DP[H[I]],MAXDP);DP [H[i]]=max (dp[h[i]],dp[j]+ (d[h[i]]-d[j]-1) *g[j]-p[j]+r[j]);} Solve (mid+1,r); cl=l; cr=mid+1; P=l;while (cl<=mid| | CR<=R) {if (Cl>mid) tmp[p]=h[cr],cr++;else if (cr>r| | G[H[CL]]<G[H[CR]]) Tmp[p]=h[cl],cl++;else tmp[p]=h[cr],cr++; p++;} for (int i=l;i<=r;i++) h[i]=tmp[i];} int main () {int Cas=0;while (1) {memset (dp,0,sizeof (DP)); scanf ("%d%d%d", &n,&s,&t); if (n==0&&dp[1 ]==0&&t==0) Break;memset (y,0,sizeof (Y)), for (int i=1,a,b,c,d;i<=n;i++) {scanf ("%d%d%d%d", &a,&b, &C,&D); h[i]=i; D[i]=a; P[i]=b; R[i]=c; G[i]=d;} n++; d[n]=t+1; H[n]=n; Sort (h+1,h+n+1,cmp); Dp[h[1]]=s; Solve (1,n);p rintf ("Case%d:%lld\n", ++cas,dp[n]);} return 0;}
Bzoj 3963 [Wf2011]machineworks