三校联训 【NOIP模拟】寻找

题面

“我有个愿望,我希望穿越一切找到你。”

这是个二维平面世界,平面上有n个特殊的果实,我从(0,0)点出发,希望得到尽量多的果实,但是出于某种特殊的原因,我的运动方式只有三种(假设当前我在(x,y)):

1、我可以走到(x+1,y)

2、我可以走到(x,y+1)

3、我可以走到(x+1,y+1)

现在我需要你的帮助,帮我找出我最多能够得到多少个果实。

对于70%的数据1<=n<=1000

对于100%的数据1<=n<=100000,-10^9<=x,y<=10^9

 

题解:

我是沙雕地把它离散化按x排序,在求y的LIS,利用树状数组优化。

#include <bits/stdc++.h>
using namespace std;
struct haha{
    int x;
    int y;
}lala[100010],fin[100010],tmp[100010];
bool cmp(haha x,haha y)
{
    if(x.x==y.x) return x.y<y.y;
    return x.x<y.x;
}
bool cmp2(haha x,haha y)
{
    if(x.y==y.y) return x.x<y.x;
    return x.y<y.y;
}
int n;
inline int lowbit(register int x)
{
    return x&(-x);
}
int c[1000010];
inline void add(register int x,register int v)
{
    while(x<=n){
        c[x]=max(c[x],v);
        x+=lowbit(x);
    }
    return;
}
inline int ask(int x)
{
    register int res=0;
    while(x>0){
        res=max(res,c[x]);
        x-=lowbit(x);
    }
    return res;
}
int f[100010];
int main()
{
    cin>>n;
    int num=0;
    for(register int i=1;i<=n;i++){
        int a,b;
        scanf("%d%d",&a,&b);
        if(a<0||b<0){
            continue;
        } 
        lala[++num].x=a;
        lala[num].y=b;
    }
    n=num;      
    sort(lala+1,lala+1+n,cmp);
    for(register int i=1;i<=n;i++){
        tmp[i]=lala[i];
        tmp[i].x=i;
    }
    sort(tmp+1,tmp+1+n,cmp2);
    tmp[0].y=999999999;
    for(register int i=1;i<=n;i++){
        fin[i]=tmp[i];
        if(tmp[i].y==tmp[i-1].y){
            fin[i].y=fin[i-1].y;
        }
        else{
            fin[i].y=i;
        }
    }
    sort(fin+1,fin+1+n,cmp);
    for(register int i=1;i<=n;i++){
        int now=fin[i].y;
        int found=ask(now);
        int op=found+1;
        f[i]=op;
        add(now,op);
    }
    register int maxn=0;
    for(register int i=1;i<=n;i++){
        maxn=max(maxn,f[i]);
    }
    cout<<maxn;
}
/*
8
0 1
1 0
1 5
2 5
3 4
3 1
5 1
5 4
*/

 

posted @ 2019-09-21 16:17  神之右大臣  阅读(241)  评论(0编辑  收藏  举报