题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1423
好坑啊。。还有公共串为0时的特殊判断,还有格式错误。。看Discuss看知道除了最后一组测试数据之外都需要空行。。
其余的会LCS打印路径就行了。
法一:
///公共最长上升子序列 #include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <algorithm> #define N 505 using namespace std; int dp[N][N],flag[N][N]; int dp1[N]; int a[N],b[N],c[N]; int n,m,k; void solve_c(int i,int j){ if(i==0||j==0) return; if(flag[i][j]==0){ solve_c(i-1,j-1); c[++k] = a[i]; }else if(flag[i][j]==1){ solve_c(i-1,j); }else solve_c(i,j-1); } void LCS(){ memset(flag,0,sizeof(flag)); for(int i=1;i<=n;i++){ for(int j=1;j<=m;j++){ if(a[i]==b[j]){ dp[i][j] = dp[i-1][j-1]+1; flag[i][j]=0; }else{ if(dp[i-1][j]>dp[i][j-1]) flag[i][j]=1; else flag[i][j]=-1; dp[i][j] = max(dp[i-1][j],dp[i][j-1]); } } } //printf("%d",dp[n][m]); k = 0; solve_c(n,m); //for(int i=1;i<=k;i++) printf("%d ",c[i]); } void LIS(){ dp1[1] = 1; int mx = 1; for(int i=2;i<=k;i++){ dp1[i]=1; for(int j=1;j<i;j++){ if(c[i]>c[j]&&dp1[i]<dp1[j]+1){ dp1[i] = dp1[j]+1; } if(mx<dp1[i]) mx=dp1[i]; } } if(k==0) mx = 0; printf("%d\n",mx); } int main() { int tcase; scanf("%d",&tcase); while(tcase--){ 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]); } memset(dp,0,sizeof(dp)); LCS(); LIS(); if(tcase) printf("\n"); } return 0; }
大神模板:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int maxn = 605; int a[maxn],b[maxn],dp[maxn]; int n,m; int LICS() { int i,j,MAX; memset(dp,0,sizeof(dp)); for(i = 1; i<=n; i++) { MAX = 0; for(j = 1; j<=m; j++) { if(a[i]>b[j] && MAX<dp[j]) MAX = dp[j]; if(a[i]==b[j]) dp[j] = MAX+1; } } MAX = 0; for(i = 1; i<=m; i++) if(MAX<dp[i]) MAX = dp[i]; return MAX; } int main() { int tcase; scanf("%d",&tcase); while(tcase--){ 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]); } int MAX = LICS(); printf("%d\n",MAX); if(tcase) printf("\n"); } return 0; }