这道题目我的做法如下:
将(x1,y1),(x2,y2)放在一个数组内记录原下标,然后进行离散化
进行DP
我的代码:(只过了样例)
#include<cstdio>
#include<iomanip>
#include<algorithm>
#define lowbit(i) i&(-i)
#define p1 (p<<1)
using namespace std;
const int N=2e5+50;
struct point{
int x,y,px,py,idx;
}a[N];
int f[N],c[N],pos[N];//pos[i]表示离散化后i号节点所对应的原下标
int n,p;
inline int Max(int a,int b){return a>b?a:b;}
bool cmp1(point p,point q){return p.x<q.x;}
bool cmp2(point p,point q){return p.y<q.y;}
inline void Insert(int x,int y){for(;x<=n;x+=lowbit(x)) c[x]=Max(c[x],y);}
inline int Query(int x)
{
int ans=0;
for(;x>0;x-=lowbit(x)) ans=Max(ans,c[x]);
return ans;
}
void Work()//离散化,将y和x分开
{
sort(a+1,a+1+p1,cmp2);
a[0].py=1;
for(int i=1;i<=p1;i++){
if(a[i].y==a[i-1].y) a[i].py=a[i-1].py;
else a[i].py=a[i-1].py+1;
}
sort(a+1,a+1+p1,cmp1);
a[0].px=1;
for(int i=1;i<=p1;i++){
if(a[i].x==a[i-1].x) a[i].px=a[i-1].px;
else a[i].px=a[i-1].px+1;
pos[a[i].idx]=i;
}
}
int main()
{
scanf("%d%d",&n,&p);
for(int i=1;i<=p;i++){
scanf("%d%d",&a[i].x,&a[i].y);
scanf("%d%d",&a[i+p].x,&a[i+p].y);
a[i].idx=i,a[i+p].idx=i+p;//将i号跳板的终点存在i+p处
}
Work();
for(int i=1;i<=p1;i++){
if(a[i].idx>p) continue;
f[i]=Query(a[i].py)-a[i].px-a[i].py+a[pos[a[i].idx+p]].px+a[pos[a[i].idx+p]].py;
Insert(a[i].py,f[i]);
}
int maxn=0;
for(int i=1;i<=p1;i++) maxn=Max(maxn,f[i]);
printf("%d\n",(n<<1)-maxn);
return 0;
}
求助各位大佬