首先需要知道,子串子序列的概念,我们以字符子串和字符子序列为例,更为形象,也能顺带着理解字符的子串和子序列:

(1)字符子串指的是字符串中连续的n个字符,如abcdefg中,ab,cde,fg等都属于它的字串。

(2)字符子序列指的是字符串中不一定连续但先后顺序一致的n个字符,即可以去掉字符串中的部分字符,但不可改变其前后顺序。如abcdefg中,acdg,bdf属于它的子序列,而bac,dbfg则不是,因为它们与字符串的字符顺序不一致。

O(n^2)的DP,O(nlogn)的二分+贪心法,以及O(nlogn)的树状数组优化的DP。

 O(n^2)暴力DP

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n;
 6 int a[1010],f[1010];
 7 int main() {
 8     cin>>n;
 9     a[0]=-2000000000;
10     for(int i=1; i<=n; i++) cin>>a[i];
11     for(int i=1; i<=n; i++)
12         for(int j=0; j<i; j++)
13             if(a[j]<a[i]) f[i]=max(f[i],f[j]+1);
14     int ans=0;
15     for(int i=1; i<=n; i++) ans=max(ans,f[i]);
16     cout<<ans<<endl;
17     return 0;
18 }
View Code

O(nlongn)二分+贪心,lower_bound

 1 #include<bits/stdc++.h>
 2 #define N 100010
 3 using namespace std;
 4 
 5 int n;
 6 int a[N],q[N];
 7 int main() {
 8     cin>>n;
 9     for(int i=1; i<=n; i++) cin>>a[i];
10     int len=0;
11     q[1]=-2e9;
12     for(int i=1; i<=n; i++) {
13         int l=1,r=len+1;
14         while(l<r) {
15             int mid=l+r+1>>1;
16             if(q[mid]<a[i]) l=mid;
17             else r=mid-1;
18         }
19         len=max(len,r);
20         q[r+1]=a[i];
21     }
22     cout<<len<<endl;
23     return 0;
24 }
View Code
 1 #include<bits/stdc++.h>
 2 #define N 100010
 3 using namespace std;
 4 
 5 int n;
 6 int a[N],q[N];
 7 int main() {
 8     cin>>n;
 9     for(int i=1; i<=n; i++) cin>>a[i];
10     int len=0;
11     q[1]=-2e9;
12     for(int i=1; i<=n; i++) {
13         int k=lower_bound(q+1,q+len+2,a[i])-q-1;
14         len=max(len,k);
15         q[k+1]=a[i];
16     }
17     cout<<len<<endl;
18     return 0;
19 }
View Code

 

求出具体的数字(倒序输出)

 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 int n;
 6 int a[1010],f[1010],g[1010];
 7 int main() {
 8     cin>>n;
 9     a[0]=-2000000000;
10     for(int i=1; i<=n; i++) cin>>a[i];
11     for(int i=1; i<=n; i++)
12         for(int j=0; j<i; j++)
13             if(a[j]<a[i])
14                 if(f[i]<f[j]+1) g[i]=j,f[i]=f[j]+1;
15     int k=1;
16     for(int i=1; i<=n; i++)
17         if(f[i]>f[k]) k=i;
18     cout<<f[k]<<endl;
19     for(int i=1,len=f[k]; i<=len; i++) cout<<a[k]<<" ",k=g[k];
20     return 0;
21 }
View Code

 

 

 Dilworth定理

 

posted on 2022-03-21 21:26  我疯故我在  阅读(53)  评论(0)    收藏  举报