Three school joint training simulation] to find [NOIP

Face questions

"I have a wish, I hope to find you through everything."

This is a two-dimensional world, there are n number of fruit on a special plane, from my point (0,0), hoping to get as many fruits, but for some particular reason, my motion only three ( suppose the current I (x, y)):

1, I can walk (x + 1, y)

2, I can walk (x, y + 1)

3, I can walk (x + 1, y + 1)

Now I need your help, help me figure out what I can get the maximum number of fruit.

For 70% of the data 1 <= n <= 1000

To 100% of the data 1 <= n <= 100000, -10 ^ 9 <= x, y <= 10 ^ 9

 

answer:

I put it discrete sand sculpture by ordering x, y in seeking the LIS, the use of Fenwick tree optimization.

#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
*/

 

Guess you like

Origin www.cnblogs.com/kamimxr/p/11563495.html