方法一
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;
}