1 /* 2 首先,dp的最开始是定义状态 dp[i][j] 表示A串的前i个,与B串的前j个,并以B[j]为结尾的LCIS 的长度. 3 状态转移方程: 4 if(A[i]==B[j]) dp[i][j]=max(dp[i-1][k])+1; ( 1 <= k < j ) 5 else dp[i][j]=dp[i-1][j]; 6 然后选择循环顺序,就可以将算法的复杂度降为n*n. 7 转自:http://www.cnblogs.com/chenhuan001/archive/2013/03/26/2982677.html 8 PS:用一维数组来记录路径老是wa,测了好多组都是对的,从昨晚一直纠结到现在,先mark,以后看,真想砸电脑*/ 9 10 #include <stdio.h> 11 #include <string.h> 12 #include <iostream> 13 using namespace std; 14 #define N 550 15 struct node 16 { 17 int x,y; 18 }path[N][N]; 19 int dp[N][N]; 20 int s[N],t[N]; 21 22 int main() 23 { 24 int t1; 25 while(scanf("%d",&t1)!=EOF) 26 { 27 while(t1--) 28 { 29 memset(path,0,sizeof(path)); 30 int n,m; 31 scanf("%d",&n); 32 for(int i=1;i<=n;i++) 33 scanf("%d",&s[i]); 34 scanf("%d",&m); 35 for(int i=1;i<=m;i++) 36 scanf("%d",&t[i]); 37 memset(dp,0,sizeof(dp)); 38 int mx=0; 39 for(int i=1;i<=n;i++) 40 { 41 mx=0; 42 int tx=0,ty=0; 43 for(int j=1;j<=m;j++) 44 { 45 dp[i][j] = dp[i-1][j]; 46 path[i][j].x=i-1; 47 path[i][j].y=j; 48 if( s[i]>t[j] && mx<dp[i-1][j]) 49 { 50 mx=dp[i-1][j]; 51 tx=i-1;//修改最长匹配的下标 52 ty=j;//修改最长匹配的下标 53 } 54 if( s[i] == t[j] ) 55 { 56 dp[i][j]=mx+1; 57 path[i][j].x=tx;//记录前一个匹配的下标 58 path[i][j].y=ty;//记录前一个匹配的下标 59 } 60 } 61 } 62 mx=-1; 63 int id; 64 for(int i=1;i<=m;i++) 65 if(dp[n][i]>mx) 66 { 67 mx=dp[n][i]; 68 id=i; 69 } 70 int save[N]; 71 int cnt=0; 72 int tx,ty; 73 tx=n; ty=id; 74 while( dp[tx][ty] != 0 ) 75 { 76 int tmpx,tmpy; 77 tmpx=path[tx][ty].x; 78 tmpy=path[tx][ty].y; 79 if(dp[tx][ty]!=dp[tmpx][tmpy]) 80 { 81 save[cnt++]=t[ty]; 82 } 83 tx=tmpx; ty=tmpy; 84 } 85 printf("%d\n",mx); 86 for(int i=cnt-1;i>=0;i--) 87 printf("%d ",save[i]); 88 printf("\n"); 89 } 90 } 91 return 0; 92 }