Rotate the coordinate system first
$x ' =x-y$
$y ' =-x-y$
For a point, the next step is to connect to any point in its upper-left corner.
According to the Dilworth theorem, the answer = the length of the longest inverse chain of the partial-order set.
F[i] is the longest anti-chain length up to I point, then
F[i]=max (F[j]) +1,j in the lower left corner of I
Sorted by x-coordinate to optimize DP with a tree array, time complexity $o (n\log N) $.
#include <cstdio> #include <algorithm> #define N 30010int n,i,j,x,y,b[n],bit[n],f[n],ans;struct p{int x, y;} a[n];inline BOOL CMP (P a,p b) {return a.x<b.x;} inline void up (Int&a,int b) {if (a<b) a=b;} inline void ins (int x,int y) {for (; x<=n;x+=x&-x) up (bit[x],y);} inline int Ask (int x) {int t=0;for (; x;x-=x&-x) up (t,bit[x]); return t;} inline int lower (int x) {int l=1,r=n,mid,t; while (l<=r) if (b[mid= (l+r) >>1]<=x) l= (t=mid) +1;else r=mid-1; return t;} inline void Read (int&a) {char c;while (!) ( ((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')); a=c-' 0 '; while (((C=getchar ()) >= ' 0 ') && (c<= ' 9 ')) (a*= Ten) +=c-' 0 ';} int main () {for (read (n), i=1;i<=n;i++) read (x), read (y), a[i].x=x-y,a[i].y=b[i]=-x-y; For (Std::sort (A+1,A+N+1,CMP), Std::sort (b+1,b+n+1), i=1;i<=n;i=j) {for (j=i;j<=n&&a[j].x==a[i].x;j++ ) Up (Ans,f[j]=ask ((A[j].y=lower (A[J].Y))-1) +1); for (j=i;j<=n&&a[j].x==a[i].x;j++) ins (a[j].y,f[j]); } return printf ("%d", ans), 0;}
BZOJ2924: [Poi1998]flat broken lines