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;
}
原文地址:https://www.cnblogs.com/DeepJay/p/12025187.html