经典dp 最长公共子序列
首先,说明一下子序列的定义……
一个序列A={a1,a2,a3,...,an},从中删除任意若干项,剩余的序列叫A的一个子序列。
很明显(并不明显……),子序列……并不需要元素是连续的……(一开始的时候思维总是以为元素是连续的,好傻啊……)
然后是公共子序列……
如果C是A的子序列,也是B的子序列,那么C是A和B的公共子序列……
公共子序列一般不止一个,最长的那个就是最长公共子序列,当然也可能不止一个……
煮个栗子……
A={1,3,6,9,5,4,8,7},B={1,6,3,4,5,7}
{1,4,7}是A和B的公共子序列
{1,3,4,7}是A和B的最长公共子序列
好了,说明的部分就到这,接下来,进入解决问题的部分……
给出序列A={a1,a2,a3...an},B={b1,b2,b3...bn}
我们用lcs[i][j]来表示A的前i项和B的前j项的最长公共子序列的长度
flag[i][j]表示这一点是由哪点继承来的,然后,开始搜索……
如果……
(1)A[i]==B[j]
那么就代表lcs[i][j]的最后一项一定是A[i],就是在lcs[i-1][j-1]接上A[i],也就是lcs[i][j]=lcs[i-1][j-1]+1,并记录flag[i][j]
(2)A[i]!=B[j]
那么lcs[i][j]=max(lcs[i-1][j-1],lcs[i][j-1]),因为既然接不上,那就继承一个长一点的留着呗,不要忘记了flag[i][j]的数字是不同的亲~
可能我说的比较简略,上一张比较好理解的图……

可能第一次看会很凌乱,仔细看吧亲……
最后按flag打出来就好了~
最后上代码
#include<stdio.h>
#include<string.h>
int lcs[][];
int flag[][];
char a[],b[];
void findlcs(char a[],char b[],int lena,int lenb){
int i,j;
for(i=;i<=lena;i++)
for(j=;j<=lenb;j++){
if(a[i-]==b[j-]){
lcs[i][j]=lcs[i-][j-]+;
flag[i][j]=;
}
else{
if(lcs[i][j-]>lcs[i-][j]){
lcs[i][j]=lcs[i][j-];
flag[i][j]=;
}
else{
lcs[i][j]=lcs[i-][j];
flag[i][j]=;
}
}
}
}
void printlcs(char a[],char b[],int lena,int lenb){
int i=lena;
int j=lenb;
int len=;
int rec[];
while(i>&&j>){
if(flag[i][j]==){
rec[len++]=a[i-];
i--,j--;
}
else if(flag[i][j]==) j--;
else if(flag[i][j]==) i--;
}
len--;
while(len>=){
printf("%c",rec[len--]);
}
printf("\n");
}
int main(){
while(~scanf("%s%s",a,b)){
int lena=strlen(a);
int lenb=strlen(b);
findlcs(a,b,lena,lenb);
printlcs(a,b,lena,lenb);
memset(flag,,sizeof(flag));
memset(lcs,,sizeof(lcs));
}
return ;
}
经典dp 最长公共子序列的更多相关文章
- hdu1159 dp(最长公共子序列)
题意:给两个字符串,求这两个字符串的最长公共子序列的长度 因为之前集训的时候做过,所以现在即使会做也并不是什么稀奇的事,依旧为了自己的浅薄感到羞愧啊``` 解法就是通过两个字符串的每个字符互相比较,根 ...
- POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 56150 Accepted: 19398 Desc ...
- poj1159--Palindrome(dp:最长公共子序列变形 + 滚动数组)
Palindrome Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 53414 Accepted: 18449 Desc ...
- 经典算法-最长公共子序列(LCS)与最长公共子串(DP)
public static int lcs(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length() ...
- HDU 1159 Common Subsequence【dp+最长公共子序列】
Common Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- POJ - 1458 Common Subsequence DP最长公共子序列(LCS)
Common Subsequence A subsequence of a given sequence is the given sequence with some elements (possi ...
- hdu 1503:Advanced Fruits(动态规划 DP & 最长公共子序列(LCS)问题升级版)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- POJ1458 Common Subsequence —— DP 最长公共子序列(LCS)
题目链接:http://poj.org/problem?id=1458 Common Subsequence Time Limit: 1000MS Memory Limit: 10000K Tot ...
- 动态规划经典算法--最长公共子序列 LCS
转移方程 代码: //法一: #include <bits/stdc++.h> using namespace std; //---------------https://lunatic. ...
随机推荐
- Android使用Home键后应用程序重启的问题
正常情况应该是在点击 home 按键后,程序在后台暂停运行,点击 后退键 才会退出应用的,但是今天遇到个问题,点击 home 键后,重新再打开应用却每次都返回应用启动页面,有些莫名其妙,一番googl ...
- FZU 2240 Daxia & Suneast's problem
博弈,$SG$函数,规律,线段树. 这个问题套路很明显,先找求出$SG$函数值是多少,然后异或起来,如果是$0$就后手赢,否则先手赢.修改操作和区间查询的话可以用线段树维护一下区间异或和. 数据那么大 ...
- C#中的委托到底是什么概念??
委托,简单理解是这样的.比如您要管您的孩子,把孩子送进了幼儿园.OK.此时您就把您的孩子委托给了幼儿园.当幼儿园放学,将孩子交还给您的手中.则是委托的回调.当然我这里的例子是说异步委托调用.您也可以同 ...
- 3-Dom
HTML DOM 对象DOM DocumentDOM ElementDOM AttributeDOM Event Document对象 每个载入浏览器的 HTML 文档都会成为 Document 对象 ...
- extjs 6.2 helloworld
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- [Jmeter]jmeter之初体验(windows下的jmeter)
一.环境准备 1.安装JDK(传送门:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.ht ...
- 各种ps特效的网址
粉笔字效果:http://www.jb51.net/photoshop/280740.html
- 从P1到P7——我在淘宝这7年(转)
作者: 赵超 发布时间: 2012-02-25 14:47 阅读: 114607 次 推荐: 153 [收藏] (一) 2011-12-08 [原文链接] 今天有同事恭喜我,我才知道自己在淘 ...
- WSAEventSelect IO复用模型
1 今天帮一学习WSAEventSelect的网友排查一个测试用服务器端recv返回0的问题,出现这个问题直观判断一般是客户端socket关闭了,可是他的代码很简单并且是本机测试,通过wireshar ...
- js实现的笛卡尔乘积-商品发布
//笛卡儿积组合 function descartes(list) { //parent上一级索引;count指针计数 var point = {}; var result = []; var pIn ...