• 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;
    }
    
  • 相关阅读:
    位运算(&)实现分享弹窗上的图标动态显示/隐藏
    MySql如何编写高效的SQL
    Xamarin跨平台移动开发解决方案
    android wireshark抓包和fiddler抓包
    webview使用总结及注意事项
    让你的Android程序更省电
    android precelable和Serialization序列化数据传输
    图片下载缓存防止OOM
    二分搜索怎么用?我和快手面试官进行了深度探讨
    二分查找详解
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12025187.html
Copyright © 2020-2023  润新知