题目链接:https://vjudge.net/contest/225715#problem/B

转载于>>>

题目大意:

给出两个序列,要求输出它们的最长公共子序列。

解题思路:

最长公共子序列模板题~

我们用dp[i][j]表示到a串第i个字符, b串第j个字符的最大匹配字符数,那么状态转移方程为:

dp[i][j]=dp[i-][j-]+      a[i]==b[j]

dp[i][j]=max(dp[i][j-], dp[i-][j])   a[i]!=b[j]

我们可以这样理解:dp[i][j]表示第a串前i个字符与b串前j个字符的最大匹配数,dp[i-1][j-1]表示a字符前i-1个字符与b串前j-1个字符的最大匹配数

如果a[i]=b[j],那么很明显dp[i][j]=dp[i-1][j-1]+1;

若a[i]!=b[j],我们假设a, b的最大匹配串为c,显然a[i], b[j]不能同时作为c的最后一个字符,那么最优匹配情况即为a[i]为c的最后一个字符或者b[j]为c的最后一个字符(这点不大好理解),即

dp[i][j]=dp[i][j-1]    a[i]是c的最后一个字符即匹配的末尾字符

dp[i][j]=dp[i-1][j]    b[j]是c的最后一个字符即匹配的末尾字符 (其实当a[i], b[j]都不是c的最后一个字符时即a[i], b[j]都不匹配时dp[i][j]=dp[i-1][j-1])

又dp要取最大值 ,即dp[i][j]=max(dp[i][j-1], dp[i-1][j])

题目还要求要输出一个最优匹配串,这个我们用vis[][]数组在dp过程中记录一下路径就好啦~

非递归输出路径

#include <bits/stdc++.h>
using namespace std;
#define MAXN 1010
int dp[MAXN][MAXN];
int vis[MAXN][MAXN];
string stra, strb;
char output[MAXN]; int cur = ; void getlcs(int i, int j)
{
while (i>&&j>) //逆推取出vis中保存的路径
{
if (vis[i][j]==) {
output[cur++] = stra[i - ];
i--; j--;
}
else if (vis[i][j] == ) {
j--;
}
else {
i--;
}
}
} int main()
{
cin >> stra >> strb;
int lena = stra.length();
int lenb = strb.length();
for (int i = ; i <= lena; i++){
for (int j = ; j <= lenb; j++) {
if (stra[i - ] == strb[j - ]) {
dp[i][j] = dp[i - ][j - ] + ;
vis[i][j] = ; //vis数组标记路径
}
else {
if (dp[i - ][j] < dp[i][j - ]) {
dp[i][j] = dp[i][j - ];
vis[i][j] = ;
}
else {
dp[i][j] = dp[i - ][j];
vis[i][j] = ;
}
}
}
}
getlcs(lena, lenb);
for (int i = cur - ; i >= ; i--) //逆向输出
printf("%c", output[i]);
cout << endl;
return ;
}

递归输出路径

#include <bits/stdc++.h>
using namespace std;
#define MAXN 1010
int dp[MAXN][MAXN];
int vis[MAXN][MAXN];
string stra, strb; void getlcs(int i, int j) { //**输出路径
if (!i || !j) { //因为i-1要>=0
return;
}
if (vis[i][j] == ) {
getlcs(i - , j - );
printf("%c", stra[i - ]);
}
else if (vis[i][j] == ) {
getlcs(i, j - );
}
else {
getlcs(i - , j);
}
} int main()
{
cin >> stra >> strb;
int lena = stra.length();
int lenb = strb.length();
for (int i = ; i <= lena; i++){
for (int j = ; j <= lenb; j++) {
if (stra[i - ] == strb[j - ]) {
dp[i][j] = dp[i - ][j - ] + ;
vis[i][j] = ; //vis数组标记路径
}
else {
if (dp[i - ][j] < dp[i][j - ]) {
dp[i][j] = dp[i][j - ];
vis[i][j] = ;
}
else {
dp[i][j] = dp[i - ][j];
vis[i][j] = ;
}
}
}
}
getlcs(lena, lenb);
cout << endl;
return ;
}

2018-05-18

51Nod-1006【LCS】+【输出路径】模板题的更多相关文章

  1. LCS以及输出路径模板

    记忆 两个for用来寻找LCS,DP是二维的,每一维代表了字符串的长度. 寻找的代码部分 if(a[i-1]==b[j-1]) dp[i][j]=dp[i-1][j-1]+1; else dp[i][ ...

  2. 51NOD 1006 最长公共子序列 Lcs 动态规划 DP 模板题 板子

    给出两个字符串A B,求A与B的最长公共子序列(子序列不要求是连续的). 比如两个串为: abcicba abdkscab ab是两个串的子序列,abc也是,abca也是,其中abca是这两个字符串最 ...

  3. hdu 1503 Advanced Fruits(LCS输出路径)

    Problem Description The company "21st Century Fruits" has specialized in creating new sort ...

  4. hdu 1503 LCS输出路径【dp】

    hdu 1503 不知道最后怎么输出,因为公共部分只输出一次.有人说回溯输出,感觉好巧妙!其实就是下图,输出的就是那条灰色的路径,但是初始时边界一定要初始化一下,因为最第一列只能向上走,第一行只能向左 ...

  5. 51nod 矩阵快速幂(模板题)

    1113 矩阵快速幂  基准时间限制:3 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 给出一个N * N的矩阵,其中的元素均为正整数.求这个矩阵的M次方.由于M次方的计算结果太大 ...

  6. Educational DP Contest F - LCS (LCS输出路径)

    题意:有两个字符串,求他们的最长公共子序列并输出. 题解:首先跑个LCS记录一下dp数组,然后根据dp数组来反着还原路径,只有当两个位置的字符相同时才输出. 代码: char s[N],t[N]; i ...

  7. poj 2007 凸包构造和极角排序输出(模板题)

    Scrambled Polygon Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10841   Accepted: 508 ...

  8. Alice拜年 模板题 /// 最短路Dijk oj1344

    题目大意: 大年初一,Alice带上拜年礼物去给N-1位亲朋好友长辈拜年,亲友真多啊,是个大家族.由于Alice才2岁,力气不大,每次只能拿一份礼物,拜完年之后,要回家取第二份礼物,然后去下一家拜年( ...

  9. PAT甲题题解-1030. Travel Plan (30)-最短路+输出路径

    模板题最短路+输出路径如果最短路不唯一,输出cost最小的 #include <iostream> #include <cstdio> #include <algorit ...

随机推荐

  1. 阿里云3台机器搭建Hadoop HA服务

    1 Mac电脑配置 阿里云配置机器 选择配置 按量付费 选择三台机器  2核8G     

  2. 变量,id()

    >>> a = 1 >>> print id(a) 2870961640 >>> b = a >>> print id(b) 2 ...

  3. vlc-android 的编译过程

    参考官方文档:https://wiki.videolan.org/AndroidCompile#Get_VLC_Source 值得注意的的地方: 1.切记安装以下工具 sudo apt-get ins ...

  4. numpy 中 shape_base提供的tile方法

    tile函数 来自于numpy.lib.shape_base 功能:重复某个数组. 比如说tile(A, n), 功能是将数组A重复n次,构成一个新的数组(行数只有1个) 比如说tile(A, n, ...

  5. Two Sum I & II & III & IV

    Two Sum I Given an array of integers, find two numbers such that they add up to a specific target nu ...

  6. freeRTOS中文实用教程1--任务

    1.前言 FreeRTOS是小型多任务嵌入式操作系统,硬实时性.本章主要讲述任务相关特性及调度相关的知识. 2. 任务的总体特点 任务的状态 (1)任务有两个状态,运行态和非运行态 (2)任务由非运行 ...

  7. 『实践』Matlab实现Flyod求最短距离及存储最优路径

    Matlab实现Flyod求最短距离及存储最优路径 一.实际数据 已知图中所有节点的X.Y坐标. 图中的节点编号:矩阵中的编号 J01-J62:1-62; F01-F60:63-122; Z01-Z0 ...

  8. windows系统实现mysql数据库数据库主从复制

    环境: master mysql服务器 192.168.8.201 slave mysql服务器 192.168.8.89 目标: 实现主从复制 1.将MySQL5.5安装文件分别拷贝到两台机器的c盘 ...

  9. [学习笔记]Javascript采用二进制浮点数和四舍五入的错误

    1.样例 var a = .3 - .2 //0.09999999999999998 var b = .2 - .1 //0.1 a == b //false 出现这样的原因在于 1.Javascri ...

  10. java开发之——[接口回调]

    一.回调的含义和用途 1. 什么是回调? 一般来说,模块之间都存在一定的调用关系,从调用方式上看,可以分为三类:同步调用.异步调用和回调.同步调用是一种阻塞式调用,即在函数A的函数体里通过书写函数B的 ...