zoukankan      html  css  js  c++  java
  • 【JZOJ4845】【NOIP2016提高A组集训第5场11.2】寻找

    题目描述

    “我有个愿望,我希望穿越一切找到你。”
    这是个二维平面世界,平面上有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

    解法

    离散化后动态规划,数据结构进行维护。

    代码

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const char* fin="find.in";
    const char* fout="find.out";
    const int inf=0x7fffffff;
    const int maxn=100007,maxt=maxn*4;
    int n,i,j,k,num,tot,totx,toty;
    int fi[maxn],ne[maxn],la[maxn],en[maxn];
    struct point{
        int x,y;
    }a[maxn];
    bool cmp(point a,point b){
        return a.y<b.y;
    }
    bool cmp1(point a,point b){
        return a.x<b.x || a.x==b.x && a.y<b.y;
    }
    void add_line(int a,int b){
        tot++;
        if (fi[a]==0){
            fi[a]=en[a]=tot;
            la[tot]=b;
        }else{
            ne[en[a]]=tot;
            en[a]=tot;
            la[tot]=b;
        }
    }
    int c[maxt],mark[maxt];
    void markdown(int l,int r,int t){
        if (mark[t]==0) return;
        c[t]=max(c[t],mark[t]);
        if (l<r){
            mark[t*2]=max(mark[t*2],mark[t]);
            mark[t*2+1]=max(mark[t*2+1],mark[t]);
        }
        mark[t]=0;
    }
    int getmax(int l,int r,int t,int v1,int v2){
        int mid=(l+r)/2;
        markdown(l,r,t);
        if (l>v2 || r<v1) return 0;
        if (l>=v1 && r<=v2) return c[t];
        return max(getmax(l,mid,t*2,v1,v2),getmax(mid+1,r,t*2+1,v1,v2));
    }
    void change(int l,int r,int t,int v1,int v2,int v){
        int mid=(l+r)/2;
        markdown(l,r,t);
        if (l>v2 || r<v1) return;
        if (l>=v1 && r<=v2){
            mark[t]=v;
            markdown(l,r,t);
            return;
        }
        change(l,mid,t*2,v1,v2,v);
        change(mid+1,r,t*2+1,v1,v2,v);
        c[t]=max(c[t*2],c[t*2+1]);
    }
    int main(){
        freopen(fin,"r",stdin);
        freopen(fout,"w",stdout);
        scanf("%d",&n);
        for (i=1;i<=n;i++){
            scanf("%d%d",&j,&k);
            if (j>=0 && k>=0){
                num++;
                a[num].x=j;
                a[num].y=k;
            }
        }
        sort(a+1,a+num+1,cmp);
        int last=a[1].y;
        a[1].y=1;
        for (i=2;i<=num;i++) if (a[i].y!=last) last=a[i].y,a[i].y=a[i-1].y+1;
        else a[i].y=a[i-1].y;
        toty=a[num].y;
        sort(a+1,a+num+1,cmp1);
        last=a[1].x;
        a[1].x=1;
        add_line(a[1].x,a[1].y);
        for (i=2;i<=num;i++){
            if (a[i].x!=last) last=a[i].x,a[i].x=a[i-1].x+1;
            else a[i].x=a[i-1].x;
            add_line(a[i].x,a[i].y);
        }
        totx=a[num].x;
        for (i=1;i<=totx;i++){
            for (k=fi[i];k;k=ne[k]){
                j=la[k];
                change(1,toty,1,j,toty,getmax(1,toty,1,1,j)+1);
            }
        }
        int ans=getmax(1,toty,1,1,toty);
        printf("%d",ans);
        return 0;
    }
  • 相关阅读:
    Git 命令使用小笔记
    一个关于if else容易迷惑的问题
    浏览器与Node环境下的Event Loop
    镜面反射
    Socket通信原理
    Git
    vba工具
    为什么要用prototype
    Oracle 列转换为行, 逗号拼接.
    JS中的phototype
  • 原文地址:https://www.cnblogs.com/hiweibolu/p/6714856.html
Copyright © 2011-2022 走看看