JZYZOJ1261 字典序最小的lis

本文介绍了一种求解字典序最小的最长上升子序列的算法实现,利用数组记录数字及其对应的最长上升子序列长度,并通过倒序遍历确定排名i的最小数字。代码使用C++编写。
 

求字典序方法:

f[i]表示i位数字的最长上升子序列长度,len为最长上升子序列长度,ans[t]为第t位答案,maxn为ans[t+1](初始化为最大值)
倒序查找f[i]==t&&a[i]<maxn的a[i],每找到一个则存入答案,t--;
 g[i]表示排名i的最小的数
原理:显然a[i]前不可能有一个a[j]<a[i]&&f[j]>=f[i]的a[j],所以倒序可行
 
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 const int bn=50010;
 8 int n,len;
 9 long long a[bn]={},f[bn]={},g[bn]={},ans[bn]={};
10 inline int search(int x){
11     int left=0,right=len,mid;
12     while(left+1<right){
13         mid=(left+right)/2;
14         if(a[g[mid]]<x){
15             left=mid;
16         }
17         else{
18             right=mid;
19         }
20     }
21     if(a[g[right]]<x){
22         left=right;
23     }
24     return left;
25 }
26 int main(){
27     //freopen("wtf.in","r",stdin);
28     int i=1;
29     while(cin>>a[i]){
30         i++;
31     }
32     n=i-1;
33     a[0]=-9999999999LL;
34     f[1]=1;
35     g[1]=1;
36     len=1;
37     for(int i=2;i<=n;i++){
38         if(a[i]>a[g[len]]){
39             len++;
40             g[len]=i;
41             f[i]=len;
42         }
43         else{
44             int t=search(a[i]);
45             f[i]=t+1;
46             if(a[g[t+1]]>a[i]){
47                 g[t+1]=i;
48             }
49         }
50     }
51     int t=len;
52     long long maxn=9999999999LL;
53     for(int i=n;i>=1;i--){
54         if(!t){
55             break;
56         }
57         if(f[i]==t&&a[i]<maxn){
58             maxn=a[i];
59             ans[t]=a[i];
60             t--;
61         }
62     }
63     for(int i=1;i<=len;i++){
64         printf("%d ",ans[i]);
65     }
66     cout<<endl;
67     return 0;
68 }
View Code

 

转载于:https://www.cnblogs.com/137shoebills/p/7783698.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值