题目链接: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. luogu P2516 [HAOI2010]最长公共子序列

    传送门 首先那个\(O(n^2)\)的dp都会吧,不会自己找博客或者问别人,或是去做模板题(误) 对以下内容不理解的,强势推荐flash的博客 我们除了原来记录最长上升子序列的\(f_{i,j}\), ...

  2. Oracle sqlplus失去响应解决方法/如何在数据库失去响应时转储状态信息(转)

    某云平台出现故障,sqlplus连接Oracle数据库,发现没有响应.数据库版本:12.1.0.2.0 查找.借鉴前人经验,成功处理此问题,参考网址:如何在数据库失去响应时转储状态信息 - Oracl ...

  3. C语言中#ifdef,#ifndef和#endif的作用

    现在规定一下头文件书写规范, 根据陈皓编写的跟我一起些makefile,一定要记住:头文件中应该只是声明,而定义应该放在C/C++文件中.否则如果出现有定义,比如头文件中有int a =2;如果有多个 ...

  4. Android NetworkInterface 的 name

    user@android:/$ ls /sys/class/net/ dummy0 lo p2p0 rev_rmnet0 rev_rmnet1 rev_rmnet2 rev_rmnet3 rmnet0 ...

  5. 基于URL的权限管理(三)

    思路:先创建一个专门的类ActiveUser用于存储用户登录的信息,主要用于存储用户id,账户,名称,菜单,权限. 认证拦截器主要是查看用户是否已登陆,如果没有转发到登陆界面,用户用账户跟密码登录时候 ...

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

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

  7. 移动端中遇到的坑(bug)!!!

    1.模拟单选点击的时候,在ios手机下,点击下面的内容选择,会出现页面闪一闪!! 解决方案:样式重置html的时候加上这句  -webkit-tap-highlight-color: rgba(0, ...

  8. Linux版本Membase无法写入default bucket的问题分析

    最近项目中使用的membase发现出了点问题,生产环境中读写各种数据都正常,可是新搭建的开发环境下,只有default bucket写不进去数据,调用store总是返回FALSE,配置文件也是一模一样 ...

  9. plsql developer如何自定义快捷键

    首选项 用户界面 编辑器 自动替换 选择替换文件,文件内容: sf=select * from df=delete from

  10. S5PV210 PWM定时器

    第一节 S5PV210的PWM定时器S5PV210共有5个32bit的PWM定时器,其中定时器0.1.2.3有PWM功能,定时器4没有输出引脚.PWM定时器使用PCLK_PSYS作为时钟源,相关知识可 ...