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

  定义dp[i][j]表示字符串a前i个和字符串b的前j个且以b[j]结尾构成的最长公共上升子序列的长度,定义一个max用来保存最大的长度。用两个循环,外层循环控制字符串a,内层循环控制字符串b。如果a[i]不等于b[j],则dp[i][j]=dp[i-1][j];如果a[i]大于b[j]而且max<dp[i-1][j],则max=dp[i-1][j];如果a[i]等于b[j],则dp[i][j]=max+1。最后的答案在dp[n][1~m]中最大的。(注意,这种情况是字符串都是从下标为1开始存的)

  下面是例题:  杭电1423

Greatest Common Increasing Subsequence

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3482    Accepted Submission(s):
1098

Problem Description
This is a problem from ZOJ 2432.To make it easyer,you
just need output the length of the subsequence.
 
Input
Each sequence is described with M - its length (1 <=
M <= 500) and M integer numbers Ai (-2^31 <= Ai < 2^31) - the sequence
itself.
 
Output
output print L - the length of the greatest common
increasing subsequence of both sequences.
 
Sample Input
1
5
1 4 2 5 -12
4
-12 1 2 4
 
Sample Output
2
 
代码如下:
 #include <iostream>
using namespace std;
int t,n,m;
int a[],b[];
int dp[][]; int LCIS()
{
int i,j;
int max;
for(i=;i<=n;i++)
{
max = ;
for(j=;j<=m;j++)
{
dp[i][j] = dp[i-][j];
if (a[i]>b[j] && max<dp[i-][j])
max = dp[i-][j];
if(a[i] == b[j])
dp[i][j] = max + ;
}
}
max = ;
for(i=;i<=m;i++)
if(max<dp[n][i])
max = dp[n][i];
return max;
} int main()
{
int i,j;
cin>>t;
while(t--)
{
cin>>n;
for(i=;i<=n;i++)
cin>>a[i];
cin>>m;
for(j=;j<=m;j++)
cin>>b[j];
memset(dp,,sizeof(dp));
cout<<LCIS()<<endl;
if (t)
cout<<endl;
}
}

  其实还有一种更牛的方法是采用一维数组,但是时间还是n^2。当i循环到k的时候,原来dp[i]表示原来的dp[k][j],因为当a[i]!=b[j]的时候dp[i]的值是不变的,沿用过去的值就行了,只有当a[i]==b[j]的时候才需要更新dp[i]的值。

代码如下:

 #include <iostream>
using namespace std;
int t,n,m;
int a[],b[];
int dp[]; int LCIS()
{
int i,j;
int max;
for(i=;i<=n;i++)
{
max = ;
for(j=;j<=m;j++)
{
if (a[i]>b[j] && max<dp[j])
max = dp[j];
if(a[i] == b[j])
dp[j] = max + ;
}
}
max = ;
for(i=;i<=m;i++)
if(max<dp[i])
max = dp[i];
return max;
} int main()
{
int i,j;
cin>>t;
while(t--)
{
cin>>n;
for(i=;i<=n;i++)
cin>>a[i];
cin>>m;
for(j=;j<=m;j++)
cin>>b[j];
memset(dp,,sizeof(dp));
cout<<LCIS()<<endl;
if (t)
cout<<endl;
}
}

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

  1. [ACM_动态规划] UVA 12511 Virus [最长公共递增子序列 LCIS 动态规划]

      Virus  We have a log file, which is a sequence of recorded events. Naturally, the timestamps are s ...

  2. hdu 1423 最长公共递增子序列 LCIS

    最长公共上升子序列(LCIS)的O(n^2)算法 预备知识:动态规划的基本思想,LCS,LIS. 问题:字符串a,字符串b,求a和b的LCIS(最长公共上升子序列). 首先我们可以看到,这个问题具有相 ...

  3. 动态规划——最长公共上升子序列LCIS

    问题 给定两个序列A和B,序列的子序列是指按照索引逐渐增加的顺序,从原序列中取出若干个数形成的一个子集,若子序列的数值大小是逐渐递增的则为上升子序列,若A和B取出的两个子序列A1和B1是相同的,则A1 ...

  4. HDU1423 最长公共上升子序列LCIS

    Problem Description This is a problem from ZOJ 2432.To make it easyer,you just need output the lengt ...

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

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

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

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

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

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

  8. CF10D LCIS 最长公共上升子序列

    题目描述 This problem differs from one which was on the online contest. The sequence a1,a2,...,an a_{1}, ...

  9. 【线型DP模板】最上上升子序列(LIS),最长公共子序列(LCS),最长公共上升子序列(LCIS)

    BEGIN LIS: 一个数的序列bi,当b1 < b2 < … < bS的时候,我们称这个序列是上升的.对于给定的一个序列(a1, a2, …, aN),我们可以得到一些上升的子序 ...

随机推荐

  1. 放弃iOS4,拥抱iOS5

      前言 苹果在2011年的WWDC大会上发布了iOS5,不过考虑到要支持iOS4.x的系统,大多数App都无法使用iOS5的新特性.现在将近1年半过去了,从我们自己的App后台的统计数据.一些第三方 ...

  2. 远程访问mysql

    转载:http://www.codesky.net/article/201108/106005.html 数据库不允许从远程访问怎么办?本文提供了三种解决方法: 1.改表法.可能是你的帐号不允许从远程 ...

  3. A quick tour of JSON libraries in Scala

    A quick tour of JSON libraries in Scala Update (18.11.2015): added spray-json-shapeless libraryUpdat ...

  4. Javascript 编程小技巧总结(部分内容借鉴他人)

    1 – 使用===,而不是== ==(或!=)操作符在需要的时候会自动执行类型转换.===(或!==)操作不会执行任何转换.它将比较值和类型,而且在速度上也被认为优于==. 2 – 使用闭包实现私有变 ...

  5. width,clientWidth,offsetWidth

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  6. .offsetLeft,.offsetTop

    *{ margin:0; padding:0} div {padding: 40px 50px;} #div1 {background: red;} #div2 {background: green; ...

  7. GIT与SVN的区别

    1.GIT是分布式的,SVN不是: 这是GIT和其它非分布式的版本控制系统,例如SVN,CVS等,最核心的区别.如果你能理解这个概念,那么你就已经上手一半了.需要做一点声明,GIT并不是目前第一个或唯 ...

  8. classmethod一个用处是创建可选类构造器

    Definition and Introduction通常来说, descriptor 是一种绑定着特殊行为属性的对象, 在访问它时行为被descriptor协议定义的方法所重载.这些方法是__get ...

  9. Docker-compose命令详解

    语法: Define and run multi-container applications with Docker. Usage:   docker-compose [-f=<arg> ...

  10. shell更改目录编码

    #!/ in/bash for i in `find ./laravel -type f` do iconv $i -f gbk -t utf8 -o ${i}.tmp && mv $ ...