题目大意:
找一组最长上升公共子序列,并把任意一组满足的情况输出出来
最长公共上升子序列不清楚可以先看这篇文章
http://www.cnblogs.com/CSU3901130321/p/4182618.html
然后在这基础上加回溯,我自己一开始利用两个一维数组写回溯,测了很多数据都没问题
但一直给segment fault,网上也看到有人跟我一样说不知道为什么,一维数组的代码主要函数先放在这里留待以后看能否解决,或者有大神帮忙解决
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int dp[N] , a[N] , b[N] , rec[N] , fa[N] , src[N] , maxn , cnt; 2 3 void LCIS(int m , int n) 4 { 5 memset(dp , 0 , sizeof(dp)); 6 memset(src , 0 , sizeof(src)); 7 memset(fa , 0 , sizeof(fa)); 8 for(int i = 1 ; i<=m ; i++){ 9 int k = 0; 10 for(int j = 1 ; j<=n ; j++){ 11 if(a[i] == b[j]){ 12 if(dp[j] < dp[k] + 1){ 13 dp[j] = dp[k] + 1; 14 src[j] = i; 15 fa[i] = src[k]; 16 } 17 } 18 if(a[i] > b[j] && dp[k] < dp[j]) k = j; 19 } 20 } 21 22 maxn = 0 , cnt = 0; 23 int s; 24 for(int i = 1 ; i <= n ; i++) 25 { 26 if(maxn < dp[i]) 27 maxn = dp[i] , s = src[i]; 28 } 29 rec[cnt++] = s; 30 while(fa[s]){ 31 rec[cnt++] = fa[s]; 32 s = fa[s]; 33 } 34 }
后来自己改成了二维数组来回溯
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 using namespace std; 5 const int N = 1005; 6 #define max(a,b) a>b?a:b 7 int dp[N] , a[N] , b[N] , rec[N] , maxn , cnt; 8 int s[N][N]; //用来回溯,记录前一次出现最大的j的位置,因为那个位置一定是会出现b[pos] = 某个a[i]的 9 10 void TraceBack(int i , int j) 11 { 12 if(i < 1 || j < 1) return ; 13 // cout<<"here: "<<i<<" "<<s[i][j]<<endl; 14 if(s[i][j] >= 0){ 15 rec[cnt++] = i; 16 17 TraceBack(i-1 , s[i][j]); 18 }else TraceBack(i-1 , j); 19 } 20 21 void LCIS(int m , int n) 22 { 23 memset(dp , 0 , sizeof(dp)); 24 memset(s , -1 , sizeof(s)); 25 for(int i = 1 ; i<=m ; i++){ 26 int k = 0; 27 for(int j = 1 ; j<=n ; j++){ 28 if(a[i] == b[j]){ 29 if(dp[j] < dp[k] + 1){ 30 dp[j] = dp[k] + 1; 31 s[i][j] = k;//记录上一次出现在最长子序列中能够进行匹配的j的位置 32 } 33 } 34 if(a[i] > b[j] && dp[k] < dp[j]) k = j; 35 } 36 } 37 38 maxn = 0 , cnt = 0; 39 int pos ; 40 //我自己写的函数原因,所以必须找到第一个出现最大值的位置pos,保证在这个位置会出现某个a[i]与其匹配 41 /*这里从后往前找和从前往后找效果一样,但是输出的序列可能不同, 42 但是题目要求只输出一种情况所以也没问题,方向找,输出的正好是样例的结果 43 for(int i = 1 ; i<=n ; i++) 也确实AC了没问题 44 */ 45 for(int i = n ; i >= 1 ; i--) 46 { 47 if(maxn < dp[i]) 48 maxn = dp[i] , pos = i; 49 } 50 TraceBack(m , pos); 51 } 52 53 int main() 54 { 55 int m , n , T; 56 scanf("%d" , &T); 57 while(T--){ 58 scanf("%d" , &m); 59 for(int i = 1 ; i<=m ; i++) 60 scanf("%d" , a+i); 61 62 scanf("%d" , &n); 63 for(int i= 1 ; i<=n ; i++) 64 scanf("%d" , b+i); 65 66 LCIS(m , n); 67 68 printf("%d " , maxn); 69 for(int i = cnt - 1 ; i>=0 ; i--) 70 printf("%d " , a[rec[i]]); 71 printf(" "); 72 if(T>0) puts(""); 73 } 74 return 0; 75 }