lis:最长递增子序列
复杂度:$O(nlgn)$

1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 int num[55],lis[55],res=0; 5 int solve(int x) 6 { 7 int a=1,b=res; 8 while(a!=b) 9 { 10 int mid=(a+b)/2; 11 if(lis[mid]>=x) 12 b=mid; 13 else 14 a=mid+1; 15 } 16 return a; 17 } 18 int main() 19 { 20 int n; 21 cin>>n; 22 for(int i=1;i<=n;i++) 23 scanf("%d",&num[i]); 24 for(int i=1;i<=n;i++) 25 { 26 if(lis[res]<=num[i]) 27 res++,lis[res]=num[i]; 28 else 29 lis[solve(num[i])]=num[i]; 30 } 31 cout<<res<<endl; 32 return 0; 33 }
lcs:最长公共子序列
复杂度$n imes m$

1 #include <cstdio> 2 #include <iostream> 3 using namespace std; 4 int dp[1000][1000]; 5 int main() 6 { 7 string a,b; 8 while(cin>>a>>b) 9 { 10 for(int i=1;i<=a.size();i++) 11 for(int j=1;j<=b.size();j++) 12 { 13 if(a[i-1]==b[j-1])dp[i][j]=dp[i-1][j-1]+1; 14 else dp[i][j]=max(dp[i-1][j],dp[i][j-1]); 15 } 16 17 char path[1000]; 18 for(int aa=a.size(),bb=b.size(),num=1;aa>=1&&bb>=1;) 19 { 20 if(a[aa-1]==b[bb-1]) 21 { 22 path[num++]=a[aa-1]; 23 aa--,bb--; 24 } 25 else 26 { 27 if(dp[aa-1][bb]>dp[aa][bb-1]) 28 aa--; 29 else bb--; 30 } 31 } 32 cout<<dp[a.size()][b.size()]<<endl; 33 for(int i=dp[a.size()][b.size()];i>=1;i--) 34 cout<<path[i]<<" "; 35 cout<<endl; 36 } 37 return 0; 38 }
lics: 最长公共上升子序列
复杂度$n imes m$

1 #include<iostream> 2 #include<string> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 const int maxn=505; 7 int n,m,num1[maxn],num2[maxn],f[maxn]; 8 int lics() 9 { 10 for(int i=0;i<=m;i++)f[i]=0; 11 int res=0; 12 for(int i=1;i<=n;i++) 13 { 14 int k=0; 15 for(int j=1;j<=m;j++) 16 { 17 if(num1[i]==num2[j]) 18 f[j]=max(f[j],k+1); 19 20 if(num2[j]<num1[i]) 21 { 22 k=max(f[j],k); 23 } 24 res=max(res,f[j]); 25 } 26 } 27 return res; 28 } 29 int main() 30 { 31 int T; 32 cin>>T; 33 for(int i=1;i<=T;i++) 34 { 35 cin>>n; 36 for(int j=1;j<=n;j++) 37 scanf("%d",&num1[j]); 38 cin>>m; 39 for(int j=1;j<=m;j++) 40 scanf("%d",&num2[j]); 41 cout<<lics()<<endl; 42 if(i!=T) 43 puts(""); 44 } 45 return 0; 46 }