poj_1458 LCS problem F.最长上升公共子序列

Description

A subsequence of a given sequence is the given sequence with some elements (possible none) left out. Given a sequence X = < x1, x2, ..., xm > another sequence Z = < z1, z2, ..., zk > is a subsequence of X if there exists a strictly increasing sequence < i1, i2, ..., ik > of indices of X such that for all j = 1,2,...,k, x ij = zj. For example, Z = < a, b, f, c > is a subsequence of X = < a, b, c, f, b, c > with index sequence < 1, 2, 4, 6 >. Given two sequences X and Y the problem is to find the length of the maximum-length common subsequence of X and Y.

Input

The program input is from the std input. Each data set in the input contains two strings representing the given sequences. The sequences are separated by any number of white spaces. The input data are correct.

Output

For each set of data the program prints on the standard output the length of the maximum-length common subsequence from the beginning of a separate line.

Sample Input

abcfbc         abfcab
programming    contest
abcd           mnp

Sample Output

4
2
0

分析:

d[i][j]表示a[1],a[2]……a[i] 和b[1],b[2]……b[i]的最长上升子序列长度.while(a[i]==a[j])  d[i][j]=d[i-1][j-1]+1;   else  d[i][j]=max{d[i-1][j],d[i][j-1]};     时间复杂度为o(n*m).

代码及简要分析:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>   //使用cin>>输入需要加上此头文件
 5 using namespace std;
 6 string a,b;
 7 int dp[1000][1000];
 8 int max(int x,int y)
 9 {
10     if(x>=y)
11         return x;
12     else
13         return y;
14 }
15
16 int main()
17 {
18     int i,j;
19     while(cin>>a)
20     {
21         cin>>b;
22         memset(dp,0,sizeof(dp));//ddp[i][j]为a[0]...a[i]和b[0]...b[j]的最长公共子序列的长度。
23         for(i=0;i<a.size();i++)
24         {
25             for(j=0;j<b.size();j++)
26             {
27                 if(a[i]==b[j])
28                     dp[i+1][j+1]=dp[i][j]+1;  //注意此从 dp[1][1]开始
29                 else
30                     dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
31
32             }
33         }
34         printf("%d\n",dp[i][j]);
35     }
36    return 0;
37 }

时间: 2024-10-23 20:47:33

poj_1458 LCS problem F.最长上升公共子序列的相关文章

最长公共子序列(LCS)、最长递增子序列(LIS)、最长递增公共子序列(LICS)

最长公共子序列(LCS) [问题] 求两字符序列的最长公共字符子序列 问题描述:字符序列的子序列是指从给定字符序列中随意地(不一定连续)去掉若干个字符(可能一个也不去掉)后所形成的字符序列.令给定的字符序列X=“x0,x1,…,xm-1”,序列Y=“y0,y1,…,yk-1”是X的子序列,存在X的一个严格递增下标序列<i0,i1,…,ik-1>,使得对所有的j=0,1,…,k-1,有xij=yj.例如,X=“ABCBDAB”,Y=“BCDB”是X的一个子序列. 考虑最长公共子序列问题如何分解成

hdoj1423 最长上升公共子序列

hdoj1423 题目分析: 两个数组a[n1] , b[n2], 求最长上升公共子序列. 我们可用一维存储 f[i] 表示 b 数组以 j 结尾, 与 a[] 数组构成的最长公共上升子序列. 对数组 d 的任意 j 位, 都枚举 a[1 ~n1]. 当a[i] == b[j] 时 , 在1 ~ j - 1中 找出 b[k] 小于 a[ i ] 并且 d[k] 的值最大. 当 a[ i ] > b [j ] 时, 在0到j-1中,对于小于a[i]的,保存f值的最优解 (保存小于a [ i ] 并

最长递增公共子序列

#include <stdio.h> #include <algorithm> #include <string.h> using namespace std; int n,m,a[505],b[505],dp[505][505]; int LICS() { int MAX,i,j; memset(dp,0,sizeof(dp)); for(i = 1; i<=n; i++) { MAX = 0; for(j = 1; j<=m; j++) { dp[i][

贼有意思[最长上升公共子序列](SAC大佬测试题)

题目描述Awson 最近越来越蠢了,一天就只知道 zyys.他定义了一个 zyys 数列:这个数列满足:1.是另外两个数列 A,B 的公共子序列;2.数列单调递增.现在他有一个问题,我们假设知道两个长度均为 N 的序列 A,B,如何去找最长的 zyys数列呢?由于他只会 zyys 了,他把这个问题交给了你.输入格式第一行包含一个整数 N,表示序列 A,B 的长度;接下来 2 行,每行 N 个数,表示序列 A,B.输出格式一行,输出最长的 zyys 数列.输入样例52 3 3 3 42 3 3 4

HDU 1423 最长上升公共子序列(LCIS)

题目大意: 给定两个数字数组a[] , b[],在这两个数组中找一个最长的公共上升子序列,输出最长的长度 #include <cstdio> #include <cstring> using namespace std; const int N = 1005; #define max(a,b) a>b?a:b int dp[N] , a[N] , b[N]; /*可以看作是每次在第一个数据中提取一个数字,然后在第二个数组中 根据相同的数字来查找最长上升子序列,f[i][j],

2017ICPC南宁赛区网络赛 The Heaviest Non-decreasing Subsequence Problem (最长不下降子序列)

Let SSS be a sequence of integers s1s_{1}s?1??, s2s_{2}s?2??, ........., sns_{n}s?n?? Each integer is is associated with a weight by the following rules: (1) If is is negative, then its weight is 000. (2) If is is greater than or equal to 10000100001

最长上升公共子序列

定义状态 F[i][j]表示以a串的前i个整数与b串的前j个整数且以b[j]为结尾构成的LCIS的长度. 状态转移方程: 现在我们来说为什么会是这样的状态转移方程呢? 对于①,因为F[i][j]是以b[j]为结尾的LCIS,如果F[i][j]>0那么就说明a[1]..a[i]中必然有一个整数a[k]等于b[j],因为a[k]!=a[i],那么a[i]对F[i][j]没有贡献,于是我们不考虑它照样能得出F[i][j]的最优值.所以在a[i]!=b[j]的情况下必然有F[i][j]=F[i-1][j

CSU-1120 病毒(最长递增公共子序列)

你有一个日志文件,里面记录着各种系统事件的详细信息.自然的,事件的时间戳按照严格递增顺序排列(不会有两个事件在完全相同的时刻发生). 遗憾的是,你的系统被病毒感染了,日志文件中混入了病毒生成的随机伪事件(但真实事件的相对顺序保持不变).备份的日志文件也被感染了,但由于病毒采用的随机感染方法,主日志文件和备份日志文件在感染后可能会变得不一样. 给出被感染的主日志和备份日志,求真实事件序列的最长可能长度. Input 输入第一行为数据组数T (T<=100).每组数据包含两行,分别描述感染后的主日志

【动态规划】最长上升公共子序列

#include <stdio.h> #include <string.h> #include <algorithm> using namespace std; int a[505], b[505]; int dp[505], path[505]; int Susake_lcis[505][505]; void Susake_LCIS(int a[], int la, int b[], int lb) { memset(path, 0, sizeof(path)); m