题目描述

This problem differs from one which was on the online contest.

The sequence a1,a2,...,an a_{1},a_{2},...,a_{n} a1​,a2​,...,an​ is called increasing, if ai<ai+1 a_{i}<a_{i+1} ai​<ai+1​ for i<n i<n i<n .

The sequence s1,s2,...,sk s_{1},s_{2},...,s_{k} s1​,s2​,...,sk​ is called the subsequence of the sequence a1,a2,...,an a_{1},a_{2},...,a_{n} a1​,a2​,...,an​ , if there exist such a set of indexes 1<=i1<i2<...<ik<=n 1<=i_{1}<i_{2}<...<i_{k}<=n 1<=i1​<i2​<...<ik​<=n that aij=sj a_{ij}=s_{j} aij​=sj​ . In other words, the sequence s s s can be derived from the sequence a a a by crossing out some elements.

You are given two sequences of integer numbers. You are to find their longest common increasing subsequence, i.e. an increasing sequence of maximum length that is the subsequence of both sequences.

输入格式

The first line contains an integer n n n ( 1<=n<=500 1<=n<=500 1<=n<=500 ) — the length of the first sequence. The second line contains n n n space-separated integers from the range [0,109] [0,10^{9}] [0,109] — elements of the first sequence. The third line contains an integer m m m ( 1<=m<=500 1<=m<=500 1<=m<=500 ) — the length of the second sequence. The fourth line contains m m m space-separated integers from the range [0,109] [0,10^{9}] [0,109] — elements of the second sequence.

输出格式

In the first line output k k k — the length of the longest common increasing subsequence. In the second line output the subsequence itself. Separate the elements with a space. If there are several solutions, output any.

题意翻译

求两个串的最长公共上升子序列。
说来惭愧,这个题看了蓝书以及洛谷题解半天才勉强想通。LCS与LIS的转移方程不难想,但这个题是LIS与LCS的组合。一般来说类似的题这种多维dp数组的含义是从前i个数/...选择一些数,但这里如果按这种状态定义的话,考虑到LIS问题的求解,我们就无法获得最后位置的信息。所以按照蓝书,这里定义dp[i][j]是A1~AI与B1~B就可以构成的以B[j]为结尾的LCIS的长度。
然后考虑转移方程。
当A[i]!=B[j]时,dp[i][j]=dp[i-1][j]。这里很好理解,A[i]与B[j]都不相等了,自然可以往前推一个。要注意的是这里dp数组第二维的含义,还是以B[j]结尾,所以i->i-1而j不变。
当A[i]==B[j]时,说明AB两串至少有A[i]或者说B[j]这个公共元素了,再次考虑dp数组的定义,以B[j]为结尾的LCIS的长度”,自然想到找到一个末尾小于B[j]的串把B[j]给接上去。因此转移方程可以写成dp[i][j]=max(dp[i-1][k]+1|k:1 to j-1)。当然从决策集合考虑还可以优化成O(n^2),但看这个题的数据范围目前这么写足以过掉。
下面来看存储答案。这里借鉴了洛谷题解的巧妙思想,再创建一个二维数组out,其含义为:out[p][q]代表以B[p]结尾的LCIS的前q个元素。这样一来,在第二重for循环中,当遇到A[i]!=B[j]时,自然不用更新;当A[i]==B[j]时,首先令out[j][1]=b[j],这代表目前LCIS起码有一个元素B[j]。然后第三重循环遍历时遇到可以接上B[j]的,如果比当前dp[i][j]大,在更新dp[i][j]的
同时也更新out[j][1~dp[i-1][k]]。
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n1,n2;
  4. int a[];
  5. int b[];
  6. int dp[][]={};
  7. int out[][];
  8. int main()
  9. {
  10. int i,j,k,m;
  11. int ans=;
  12. cin>>n1;
  13. memset(dp,,sizeof(dp));
  14. for(i=;i<=n1;i++)
  15. {
  16. scanf("%d",&a[i]);
  17. }
  18. cin>>n2;
  19. for(j=;j<=n2;j++)
  20. {
  21. scanf("%d",&b[j]);
  22. }
  23. dp[][]=;
  24. int pos=;
  25. for(i=;i<=n1;i++)
  26. {
  27. for(j=;j<=n2;j++)
  28. {
  29.  
  30. if(a[i]!=b[j])
  31. {
  32. dp[i][j]=dp[i-][j];//和之前一样的话没必要更新输出串
  33. }
  34. else
  35. {
  36. //
  37. dp[i][j]=;//相等的话最小也为1
  38. out[j][]=b[j];//相等的话最少有一个b[j]
  39. //
  40. for(k=;k<j;k++)//找到最长的进行拼接
  41. {
  42. if(b[k]<b[j])
  43. {
  44. if(dp[i-][k]+>dp[i][j])//大于当前答案的话
  45. {
  46. dp[i][j]=dp[i-][k]+;//更新dp数组
  47. for(m=;m<=dp[i-][k];m++)//更新out数组对应位置的元素
  48. {
  49. out[j][m]=out[k][m];
  50. }
  51. out[j][dp[i][j]]=b[j];//把b[j]加上去
  52. }
  53. }
  54. }
  55. }
  56. ans=max(ans,dp[i][j]);//更新LCIS的长度
  57. if(ans==dp[i][j])pos=j; //找到对应的位置
  58. }
  59. }
  60. cout<<ans<<endl;
  61. for(i=;i<=ans;i++)//输出LCIS
  62. {
  63. cout<<out[pos][i]<<' ';
  64. }
  65.  
  66. return ;
  67. }

CF10D LCIS 最长公共上升子序列的更多相关文章

  1. [CodeForces10D]LCIS(最长公共上升子序列) - DP

    Description 给定两个数列,求最长公共上升子序列,并输出其中一种方案. Input&Output Input 第一行一个整数n(0<n<=500),数列a的长度. 第二行 ...

  2. LCIS最长公共上升子序列

    最长公共上升子序列LCIS,如字面意思,就是在对于两个数列A和B的最长的单调递增的公共子序列. 这道题目是LCS和LIS的综合. 在LIS中,我们通过两重循环枚举当序列以当前位置为结尾时,A序列中当前 ...

  3. LCIS 最长公共上升子序列问题DP算法及优化

    一. 知识简介 学习 LCIS 的预备知识: 动态规划基本思想, LCS, LIS 经典问题:给出有 n 个元素的数组 a[] , m 个元素的数组 b[] ,求出它们的最长上升公共子序列的长度. 例 ...

  4. LCIS(最长公共上升子序列)Vijos1264神秘的咒语

    描述 身为拜月教的高级间谍,你的任务总是逼迫你出生入死.比如这一次,拜月教主就派你跟踪赵灵儿一行,潜入试炼窟底. 据说试炼窟底藏着五行法术的最高法术:风神,雷神,雪妖,火神,山神的咒语.为了习得这些法 ...

  5. LCIS 最长公共上升子序列

    这个博客好久没写了,这几天为了准备清华交叉研究院的夏令营,在复习大一大二ACM训练时的一些基础算法,正好碰到LICS,发现没有写在博客里,那就顺便记录一下好了. 参考链接:http://blog.cs ...

  6. LCIS(最长公共上升子序列)模板

    求出LCIS并输出其路径. 1 #include <iostream> 2 #include <cstdio> 3 #include <string> 4 #inc ...

  7. CodeForces 10D. LCIS 最长公共上升子序列模板题 + 打印路径

    推荐一篇炒鸡赞的blog. 以下代码中有打印路径. #include <algorithm> #include <iostream> #include <cstring& ...

  8. 【简单dp】poj 2127 Greatest Common Increasing Subsequence【最长公共上升子序列】【模板】

    Sample Input 5 1 4 2 5 -12 4 -12 1 2 4 Sample Output 2 1 4 题目:给你两个数字序列,求出这两个序列的最长公共上升子序列.输出最长的长度,并打表 ...

  9. 最长公共上升子序列(LCIS)

    最长公共上升子序列慕名而知是两个字符串a,b的最长公共递增序列,不一定非得是连续的.刚开始看到的时候想的是先用求最长公共子序列,然后再从其中找到最长递增子序列,可是仔细想一想觉得这样有点不妥,然后从网 ...

随机推荐

  1. 寒假安卓app开发学习记录(7)

    今天学习了Intent的基本用法.Intent是什么?Intent在Android中的核心作用就是“跳转”(Android中的跳转机制),同时可以携带必要的信息,将Intent作为一个信息桥梁.最常用 ...

  2. hadoop学习笔记(八):hadoop2.x的高可用环境搭建

    本文原创,转载请注明作者及原文链接 高可用集群的搭建: 几个集群的启动顺序问题: 1.先启动zookeeper --->zkServer.sh start 2.启动journalNodes集群  ...

  3. PTPX-功耗分析总结

    使用PrimeTime PX进行功耗分析有两种:一种是平均功耗的分析Averaged power analysis,一种是Time-based power analysis.   电路的功耗主要有两种 ...

  4. 在同一个tomcat下部署多个springboot项目时,springboot项目无法正常启动的问题

    这个问题是基于,不使用springboot内置的tomcat会产生(即使用自己的tomcat时). 今天在部署springboot项目的时候遇到了一个问题,怎么部署都访问不了,在网上查了很多原因,什么 ...

  5. 使用maven构建项目时,SSM和springboot项目的打包与云服务器部署

    下面讲讲如何打包SSM和springboot项目,并部署到云服务器上. 由于使用的IDE不同,有的使用eclipse,有的使用idea,所以如果在IDE中按照 maven clean 再 maven ...

  6. poj 3281Dining(网络流 拆点)

    题目链接:http://poj.org/problem?id=3281 题目大意:John养了N只奶牛,他为奶牛准备了F个食物和D个饮料,但是每只奶牛只对其中的一些饮料和食物感兴趣,现在请制定一些方案 ...

  7. 喵星之旅-狂奔的兔子-基于docker的rabbitmq安装

    docker安装参考:喵星之旅-狂奔的兔子-docker安装和基本使用 一.查询镜像名称 由于我们要安装的是有web管理页面的,不能直接拉取,需要指定版本. 登录docker仓库查询:https:// ...

  8. HADOOP_SECURE_DN_USER has been replaced by HDFS_DATANODE_SECURE_USER

    这个问题可能是我第一个遇到吧,hadoop启动时WARNING: HADOOP_SECURE_DN_USER has been replaced by HDFS_DATANODE_SECURE_USE ...

  9. 1.3 eclipse快捷键

    来源:http://blog.csdn.net/dashuxiaoai/article/details/8737928 另:Eclipse快捷键 10个最有用的快捷键  http://www.cnbl ...

  10. python+tkinter制作一个可自定义的动态时钟及详细解释,珍藏版

    1.效果图 2.完整代码 #第1步:导出模块 from tkinter import * import math,time #第2步:定义窗口的相关设置 root = Tk() root.title( ...