zoukankan      html  css  js  c++  java
  • Uva481 (LIS+路径打印)

    方法一

    last数组储存在栈中的对应位置
    题目要求找最后一个lis,就直接从最后向前遍历
    因为后面能够更新栈中元素的元素,下标靠后
    所以不会影响寻找;
    AC代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int N=1e6+5;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    int tot,a[N],last[N],sta[N],ans[N];
    int main()
    {
        int x;
        while(scanf("%d",&x)!=EOF) a[++tot]=x;
        int top=0;
        sta[++top]=a[1];
        last[top]=1;
        for(int i=2;i<=tot;i++)
        {
            if(a[i]>sta[top])
            {
                sta[++top]=a[i];
                last[i]=top;
            }
            else
            {
                int pos=lower_bound(sta+1,sta+top+1,a[i])-sta;
                last[i]=pos;
                sta[pos]=a[i];
            }
        }
        printf("%d
    -
    ",top);
        int len=top;
        for(int i=tot;i;i--)//查找lis
        {
            if(last[i]==len) ans[len--]=a[i];
            if(len==0) break;
        }
        for(int i=1;i<=top;i++) printf("%d
    ",ans[i]);
        return 0;
    }
    /*
    -7
    10
    9
    2
    3
    8
    8
    6
    */
    

    方法二

    id存栈内元素在原数组的索引,last[] 类似于链表的思想,连接 自己在栈内位置的前一个位置的元素。
    同样该思想也是基于 后面能够更新栈中元素的元素,下标靠后 的思想。
    只有后面元素把top值更新了或者等于top(要找最后一个lis),那么last[ top ]即表头才会被更新。

    AC代码

    #include<cstdio>
    #include<cstring>
    #include<cctype>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    const int N=1e6+5;
    const int inf=0x3f3f3f3f;
    const int mod=1e9+7;
    #define ls (i<<1)
    #define rs (i<<1|1)
    #define fi first
    #define se second
    #define mk make_pair
    #define mem(a,b) memset(a,b,sizeof(a))
    LL read()
    {
        LL x=0,t=1;
        char ch;
        while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
        while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
        return x*t;
    }
    int tot,a[N],last[N],sta[N],id[N],ans[N];
    int main()
    {
        //freopen("input.txt","r",stdin);
        //freopen("output.txt","wt+",stdout);
        int x;
        while(scanf("%d",&x)!=EOF) a[++tot]=x;
        int top=0;
        sta[++top]=a[1];
        last[top]=0;
        id[top]=1;
        for(int i=2;i<=tot;i++)
        {
            if(a[i]>sta[top])
            {
                //printf("i=%d a[i]=%d sta[top]=%d
    ",i,a[i],sta[top]);
                sta[++top]=a[i];
                id[top]=i;
                last[i]=id[top-1];
            }
            else
            {
                int pos=lower_bound(sta+1,sta+top+1,a[i])-sta;
                //printf("i=%d pos=%d
    ",i,pos);
                last[i]=id[pos-1];
                sta[pos]=a[i];
                id[pos]=i;
            }
        }
        printf("%d
    -
    ",top);
        int k=id[top],cnt=0;
        while(k)
        {
            ans[++cnt]=a[k];
            k=last[k];
        }
        for(int i=cnt;i;i--) printf("%d
    ",ans[i]);
        return 0;
    }
    
  • 相关阅读:
    Android----paint触摸轨迹监听
    Android----ListView入门知识--各种Adapter配合使用
    Android------自定义ListView详解
    Android----drawable state各个属性详解----ListView几个比较特别的属性:
    Android------三种监听OnTouchListener、OnLongClickListener同时实现即其中返回值true或者false的含义
    Android----基于多触控的图片缩放和拖动代码实现
    Android-----View绘制流程以及invalidate()等相关方法分析 .
    android-------手写签名系统的设计与实现之实现画笔设置
    安卓APP动态调试-IDA实用攻略
    win10怎么关闭把管理员权限
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025187.html
Copyright © 2011-2022 走看看