E05 线性DP U197280 最长公共子序列
E05 线性DP 最长公共子序列_哔哩哔哩_bilibili
// 线性DP O(n^2) #include<bits/stdc++.h> using namespace std; const int N=1010; int n,m; char a[N],b[N]; int f[N][N]; //f[i,j]表示前 i,j 个字符中的最长公共子序列的长度 int main(){ cin>>a+1>>b+1; n=strlen(a+1); m=strlen(b+1); for(int i=1; i<=n; i++){ for(int j=1; j<=m; j++){ if(a[i]==b[j]) f[i][j]=f[i-1][j-1]+1; else f[i][j]=max(f[i-1][j],f[i][j-1]); } } cout<<f[n][m]; }
// 线性DP 滚动数组 O(n^2) #include<bits/stdc++.h> using namespace std; const int N=10010; int n,m; char a[N],b[N]; int f[2][N]; //f[i,j]表示前 i,j 个字符中的最长公共子序列的长度 int main(){ cin>>a+1>>b+1; n=strlen(a+1); m=strlen(b+1); int u=0; for(int i=1; i<=n; i++){ u^=1; for(int j=1; j<=m; j++){ if(a[i]==b[j]) f[u][j]=f[u^1][j-1]+1; else f[u][j]=max(f[u^1][j],f[u][j-1]); } } cout<<f[u][m]; }
// 线性DP 滚动数组 O(n^2) #include<bits/stdc++.h> using namespace std; const int N=10005; int n,m; char a[N],b[N]; int f[2][N]; int main(){ cin>>a+1>>b+1; n=strlen(a+1);m=strlen(b+1); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i]==b[j]) f[1][j]=f[0][j-1]+1; else f[1][j]=max(f[0][j],f[1][j-1]); } for(int j=1; j<=m; j++) f[0][j]=f[1][j]; } cout<<f[1][m]; }
// 线性DP 滚动数组 O(n^2) #include<bits/stdc++.h> using namespace std; const int N=5010,mod=1e8; int n,m; char a[N],b[N]; int f[2][N],g[2][N]; int main(){ scanf("%s %s",a+1,b+1); n=strlen(a+1)-1; m=strlen(b+1)-1; for(int k=0; k<=m; k++) g[0][k]=1; g[1][0]=1; int u=0; for(int i=1; i<=n; i++){ u^=1; for(int j=1; j<=m; j++){ if(a[i]==b[j]) f[u][j]=f[u^1][j-1]+1; else f[u][j]=max(f[u^1][j],f[u][j-1]); g[u][j]=0; if(a[i]==b[j]&&f[u][j]==f[u^1][j-1]+1) g[u][j]+=g[u^1][j-1]; if(f[u][j]==f[u^1][j]) g[u][j]+=g[u^1][j]; if(f[u][j]==f[u][j-1]) g[u][j]+=g[u][j-1]; if(f[u][j]==f[u^1][j-1]) g[u][j]-=g[u^1][j-1]; //容斥 g[u][j]%=mod; } } printf("%d\n%d",f[u][m],g[u][m]); }
// 二分+贪心 O(nlogn) #include<bits/stdc++.h> using namespace std; const int N=100010; int n,x,id[N],p[N],len; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&x),id[x]=i; memset(p,0x3f,sizeof p); for(int i=1;i<=n;i++){ scanf("%d",&x); *lower_bound(p+1,p+n+1,id[x])=id[x]; //用x的出现次序替换队列p中元素 } len=lower_bound(p+1,p+n+1,p[0])-p-1; //第一个 0x3f 左边是公共子序列 printf("%d",len); }
// 线性DP O(n^3) #include<bits/stdc++.h> using namespace std; const int N=3005; int n,a[N],b[N],ans; int f[N][N]; //f[i,j]表示前(i,j)个数且以 b[j] 为结尾的最长公共上升子序列的长度 int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ if(a[i]!=b[j]) f[i][j]=f[i-1][j]; else{ int mx=0; for(int k=1;k<j;k++) if(a[i]>b[k])mx=max(mx,f[i-1][k]); f[i][j]=mx+1; } ans=max(ans,f[i][j]); } } printf("%d",ans); }
// 线性DP O(n^2) #include<bits/stdc++.h> using namespace std; const int N=3005; int n,a[N],b[N],ans; int f[N][N]; //f[i,j]表示前(i,j)个数且以 b[j] 为结尾的最长公共上升子序列的长度 int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++){ int mx=0; for(int j=1;j<=n;j++){ if(a[i]!=b[j]) f[i][j]=f[i-1][j]; else f[i][j]=mx+1; //用 1~[i-1,j-1] 的LCIS接上a[i] if(a[i]>b[j]) mx=max(mx,f[i-1][j]); //保存 1~[i-1,j] 以a[i]结尾的LCIS的长度 ans=max(ans,f[i][j]); } } printf("%d",ans); }
// 线性DP O(n^2) #include<bits/stdc++.h> using namespace std; const int N=3005; int n,m,a[N],b[N],ans; int f[N][N]; //f[i,j]表示前(i,j)个数且以 b[j] 为结尾的最长公共上升子序列的长度 int pre[N][N],path[N]; int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); scanf("%d",&m); for(int i=1;i<=m;i++) scanf("%d",&b[i]); for(int i=1;i<=n;i++){ int mx=0,pos=0; for(int j=1;j<=m;j++){ if(a[i]!=b[j]) f[i][j]=f[i-1][j],pre[i][j]=j; else f[i][j]=mx+1,pre[i][j]=pos; if(a[i]>b[j]) if(f[i-1][j]>mx) mx=f[i-1][j],pos=j; } } int mm; for(int j=1;j<=m;j++)if(f[n][j]>ans){ ans=f[n][j]; mm=j; } int i=n,j=mm,cnt=0; while(i||j){ if(pre[i][j]!=j) path[++cnt]=b[j]; j=pre[i][j]; i--; } if(ans==0) {puts("0");return 0;} printf("%d\n",ans); for(int i=cnt;i>=1;i--)printf("%d ",path[i]); return 0; }
 
                    
                     
                    
                 
                    
                 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号