2000:最长公共子上升序列

http://blog.csdn.net/persuing_truth/article/details/57406259

总时间限制: 

10000ms 
内存限制: 
65536kB
描述
给定两个整数序列,写一个程序求它们的最长上升公共子序列。
当以下条件满足的时候,我们将长度为N的序列S 1 , S 2 , . . . , S N 称为长度为M的序列A 1 , A 2 , . . . , A M的上升子序列:

存在 1 <= i 1 < i 2 < . . . < i N <= M ,使得对所有 1 <= j <=N,均有S j = A ij,且对于所有的1 <= j < N,均有S j < S j+1

输入
每个序列用两行表示,第一行是长度M(1 <= M <= 500),第二行是该序列的M个整数A i (-2 31 <= A i < 2 31 )
输出
在第一行,输出两个序列的最长上升公共子序列的长度L。在第二行,输出该子序列。如果有不止一个符合条件的子序列,则输出任何一个即可。
样例输入
5
1 4 2 5 -12
4
-12 1 2 4
样例输出
2
1 4
  • 查看 
  • 提交 
  • 统计 
  • 提问
    • /* 
       * 关于LCIS的具体思路及时间和空间复杂度的优化见http://blog.csdn.net/wall_f/article/details/8279733(这个博主写的挺好的 不过有些地方有笔误 注意点不影响阅读) 
         1. 这题不支持Special Judge...  
         so设置状态转移方程的时候 要设置成LCIS是以第一个数组的第j个元素结尾的 而不能是第二个数组 - - 就是这么坑0-0 
         2. 记录LCIS中的元素并输出 dp的时候对结构体dp  结构体中vector记录LCIS中元素。 
       */  
      #include<iostream>  
      #include<vector>  
      using namespace std;  
      struct Node {  
          int val = 0;  
          vector<int>v;  
      };  
      int main() {  
          int a[501], b[501];  
          Node dp[501];  
          int m, n;  
          cin >> m;  
          for (int i = 1; i <= m; i++)  
              cin >> a[i];  
          cin >> n;  
          for (int i = 1; i <= n; i++)  
              cin >> b[i];  
          for (int i = 1; i <= n; i++)  
          {  
              Node Max;  
              for (int j = 1; j <= m; j++) {  
                  if (b[i] > a[j] && dp[j].val > Max.val)  
                      Max = dp[j];  
                  if (b[i] == a[j]) {  
                      dp[j].val = Max.val + 1;  
                      dp[j].v = Max.v;  
                      dp[j].v.push_back(b[i]);  
                  }  
              }  
          }  
          Node Max = dp[1];  
          for (int i = 2; i <= m; i++) {  
              if (dp[i].val > Max.val)  
                  Max = dp[i];  
          }  
          cout << Max.val << endl;  
          for (int i = 0; i < Max.v.size(); i++)  
              cout << Max.v[i] << " ";  
          cout << endl;  
          return 0;  
      }  


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值