【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]

P1439 【模板】最长公共子序列

 此思路详见luogu第一个题解 一个很妙的离散化

刘汝佳蓝书上面的LIS 详见蓝书

d[i]以i为结尾的最长上升子序列的长度     g[i]表示d值为i的最小状态的编号即长度为i的上升子序列的最小末尾值

1 for(int i=1;i<=n;++i) scanf("%d",&a[i]);
2 for(int i=1;i<=n;++i)
3 {
4     int k=lower_bound(g+1,g+1+n,a[i])-g;
5     d[i]=k;
6     g[k]=cb[i]; 
7 }

 

只是手写二分的时候要注意超多细节 巨难受【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]

【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define rg register
 4 const int N=100000+5,inf=0x3f3f3f3f;
 5 int n,a[N],b[N],ca[N],cb[N];
 6 int g[N],d[N],len=0;
 7 
 8 template<class t>void rd(t &x)
 9 {
10     x=0;int w=0;char ch=0;
11     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
12     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
13     x=w?-x:x;
14 }
15 
16 int main()
17 {
18     rd(n);
19     memset(g,inf,sizeof(g));
20     for(rg int i=1;i<=n;++i) rd(a[i]),ca[a[i]]=i;
21     for(rg int i=1;i<=n;++i) rd(b[i]),cb[i]=ca[b[i]];
22     for(rg int i=1;i<=n;++i)
23     {
24         int k=lower_bound(g+1,g+1+n,cb[i])-g;
25         g[k]=cb[i];
26         len=max(len,k);
27     }
28     printf("%d",len);
29     return 0; 
30 } 
100昏 用lower_bound 【luogu1439】 【模板】最长公共子序列 [动态规划][LIS最长上升子序列][离散化]
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define rg register
 4 const int N=100000+5,inf=0x3f3f3f3f;
 5 int n,a[N],b[N],ca[N],cb[N];
 6 int g[N],len=0;
 7 
 8 template<class t>void rd(t &x)
 9 {
10     x=0;int w=0;char ch=0;
11     while(!isdigit(ch)) w|=ch=='-',ch=getchar();
12     while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
13     x=w?-x:x;
14 }
15 
16 int find(int x)
17 {
18     int l=1,r=len,mid;
19     while(l<=r)
20     {
21         mid=(l+r)>>1;
22         if(x>g[mid]) l=mid+1;
23         else r=mid-1;
24     }
25     return l;
26 }
27 
28 int main()
29 {
30     rd(n);
31     memset(g,inf,sizeof(g));
32     for(rg int i=1;i<=n;++i) rd(a[i]),ca[a[i]]=i;
33     for(rg int i=1;i<=n;++i) rd(b[i]),cb[i]=ca[b[i]];
34     for(rg int i=1;i<=n;++i)
35     {
36         int k=find(cb[i]);
37         g[k]=cb[i];
38         len=max(len,k);
39     }
40     printf("%d",len);
41     return 0; 
42 } 
100昏 手写二分

 

上一篇:全差分运放浅析(转载)


下一篇:题解 P5301 【[GXOI/GZOI2019]宝牌一大堆】