【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)
由于noi OJ上没有Special Judge,所以我是没有在这上面AC的。但是在POJ上A了。
题意如标题。
解法:f[i][j]表示a串前i个和b串前j个且包含b[j]的最长公共上升子序列长度
首先,可用3重循环得到,k循环找到b串j之前的最大长度子序列的结尾字符b[k],得以更新现在f[i][j]的状态。
然后,由于k循环的都在j之前,可发现k循环可略去,直接将满足上升的字符用临时变量存,每次j循环的都更新就好了。
具体上,最初f[i][j]=f[i-1][j],先继承好上一个状态,a[i]不加入选出的子序列(平常DP有表示“前...”的初始值都是像这样先可由前一个状态推出的)于是a[i]=b[j]时,就由之前存的最佳答案+1得到。最后由于这次的j是为了下次的a[i]=b[xx]做准备,所以若满足b[j]<a[i]且当前答案最佳,就更新临时储存的临时变量。
另外,打印路径有2种方法。用1维数组存是不行的,因为相同的一个i在和不同的j时,不能直接覆盖掉原来的答案。
1.用2个数组分别记录每次a[i]=b[j]之后ans+1的i和j;
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 typedef long long LL;
8 const int N=510;
9 LL a[N],b[N],s[N];
10 int f[N][N],u[N][N],v[N][N];
11
12 int main()
13 {
14 int n,m;
15 scanf("%d",&n);
16 for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
17 scanf("%d",&m);
18 for (int i=1;i<=m;i++) scanf("%lld",&b[i]);
19 memset(f,0,sizeof(f));
20 memset(u,0,sizeof(u));
21 memset(v,0,sizeof(v));
22 for (int i=1;i<=n;i++)
23 {
24 int p=0,q=0;
25 for (int j=1;j<=m;j++)
26 {
27 f[i][j]=f[i-1][j];
28 u[i][j]=u[i-1][j],v[i][j]=v[i-1][j];
29 if (a[i]==b[j]) f[i][j]=f[p][q]+1,u[i][j]=p,v[i][j]=q;
30 else if (a[i]>b[j] && f[i][j]>f[i][q]) p=i-1,q=j;
31 }
32 }
33 int t=1,cnt=0;
34 for (int j=2;j<=m;j++)
35 if (f[n][j]>f[n][t]) t=j;
36 printf("%d\n",f[n][t]);
37 s[++cnt]=b[t];
38 int x=n,y=t,xx,yy;
39 while (f[x][y])
40 s[++cnt]=b[y],xx=x,yy=y,x=u[xx][yy],y=v[xx][yy];
41 for (int i=cnt;i>=1;i--) printf("%lld ",s[i]);
42 return 0;
43 }
1
2.只存每次加入子序列的b[j],不断一个个递减i找到与b[j]匹配的a[i],得到下一个j的pre[i][j]。
1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 using namespace std;
6
7 typedef long long LL;
8 const int N=510;
9 LL a[N],b[N],s[N];
10 int f[N][N],pre[N][N];
11
12 int main()
13 {
14 int n,m;
15 scanf("%d",&n);
16 for (int i=1;i<=n;i++) scanf("%lld",&a[i]);
17 scanf("%d",&m);
18 for (int i=1;i<=m;i++) scanf("%lld",&b[i]);
19 memset(f,0,sizeof(f));
20 memset(pre,0,sizeof(pre));
21 for (int i=1;i<=n;i++)
22 {
23 int p=0;
24 for (int j=1;j<=m;j++)
25 {
26 f[i][j]=f[i-1][j];
27 if (a[i]==b[j]) f[i][j]=f[i][p]+1,pre[i][j]=p;
28 else if (a[i]>b[j] && f[i-1][j]>f[i-1][p]) p=j;
29 }
30 }
31 int t=1,cnt=0;
32 for (int j=2;j<=m;j++)
33 if (f[n][j]>f[n][t]) t=j;
34 printf("%d\n",f[n][t]);
35 int x=n,y=t;
36 while (f[x][y])
37 {
38 while(a[x]!=b[y]&&x) x--;
39 s[++cnt]=b[y];
40 y=pre[x][y];
41 }
42 for (int i=cnt;i>=1;i--) printf("%lld ",s[i]);
43 return 0;
44 }
2
【noi 2.6_2000】&【poj 2127】 最长公共子上升序列 (DP+打印路径)的更多相关文章
- POJ 2127 最长公共上升子序列
动态规划法: #include <iostream> #include <cstdio> #include <fstream> #include <algor ...
- poj 2774 最长公共子--弦hash或后缀数组或后缀自己主动机
http://poj.org/problem?id=2774 我想看看这里的后缀数组:http://blog.csdn.net/u011026968/article/details/22801015 ...
- openjudge-NOI 2.6-2000 最长公共子上升序列
题目链接:http://noi.openjudge.cn/ch0206/2000/ 题解: 裸题,不解释(题目有毒) #include<cstdio> #include<algori ...
- CodeForces 10D. LCIS 最长公共上升子序列模板题 + 打印路径
推荐一篇炒鸡赞的blog. 以下代码中有打印路径. #include <algorithm> #include <iostream> #include <cstring& ...
- poj 2774 最长公共子串 后缀数组
Long Long Message Time Limit: 4000MS Memory Limit: 131072K Total Submissions: 25752 Accepted: 10 ...
- POJ 1458 最长公共子序列(dp)
POJ 1458 最长公共子序列 题目大意:给出两个字符串,求出这样的一 个最长的公共子序列的长度:子序列 中的每个字符都能在两个原串中找到, 而且每个字符的先后顺序和原串中的 先后顺序一致. Sam ...
- 使用后缀数组寻找最长公共子字符串JavaScript版
后缀数组很久很久以前就出现了,具体的概念读者自行搜索,小菜仅略知一二,不便讨论. 本文通过寻找两个字符串的最长公共子字符串,演示了后缀数组的经典应用. 首先需要说明,小菜实现的这个后缀数组算法,并非标 ...
- uva 10066 The Twin Towers (最长公共子)
uva 10066 The Twin Towers 标题效果:最长公共子. 解题思路:最长公共子. #include<stdio.h> #include<string.h> # ...
- 最长公共子序列与最长公共字串 (dp)转载http://blog.csdn.net/u012102306/article/details/53184446
1. 问题描述 子串应该比较好理解,至于什么是子序列,这里给出一个例子:有两个母串 cnblogs belong 比如序列bo, bg, lg在母串cnblogs与belong中都出现过并且出现顺序与 ...
随机推荐
- 【JavaWeb】Filter 过滤器
Filter 过滤器 简介 Filter 过滤器是 JavaWeb 三大组件之一 Filter 过滤器是 JavaEE 的规范,也就是接口 Filter 过滤器的作用是 拦截请求,过滤响应 拦截请求的 ...
- 【Flutter】可滚动组件之SingleChildScrollView
前言 SingleChildScrollView类似于Android中的ScrollView,它只能接收一个子组件. 接口描述 const SingleChildScrollView({ Key ke ...
- Neo4j 图数据库查询
Cypher 介绍 Cypher 介绍:作为Neo4j的查询语言,"Cypher"是一个描述性的图形查询语言,允许不必编写图形结构的遍历代码对图形存储有表现力和效率的查询.Cyph ...
- 目录遍历 - Pikachu
概述: 在web功能设计中,很多时候我们会要将需要访问的文件定义成变量,从而让前端的功能便的更加灵活. 当用户发起一个前端的请求时,便会将请求的这个文件的值(比如文件名称)传递到后台,后台再执行其对应 ...
- [Usaco2008 Nov]Buying Hay 购买干草
题目描述 约翰的干草库存已经告罄,他打算为奶牛们采购H(1≤H≤50000)磅干草,他知道N(1≤N≤100)个干草公司,现在用1到N给它们编号.第i个公司卖的干草包重量为Pi(1≤Pi≤5000)磅 ...
- 微信登录4-开发回调URL
一.准备 1.引入pom依赖 在要使用HttpClient的项目中加入依赖 <!--httpclient--> <dependency> <groupId>org. ...
- 微信小程序 发送模板消息的功能实现
背景 - 小程序开发的过程中,绝大多数会满足微信支付 - 那么,作为友好交互的体现,自然就会考虑到支付后的消息通知咯 - 所以,我的小程序项目也要求完成这个效果,so.分享一下自己的实现步骤,以方便道 ...
- Py装饰器
装饰器: 1.定义,什么是装饰器 装饰器本质是一个函数,它是为了给其他函数添加附加功能 2.装饰器的两个原则 原则1 不修改被修饰函数的源代码原则2 不修改被修饰函数的调用方式 3.首先来看一 ...
- 基于Python的接口自动化-unittest测试框架和ddt数据驱动
引言 在编写接口自动化用例时,我们一般针对一个接口建立一个.py文件,一条接口测试用例封装为一个函数(方法),但是在批量执行的过程中,如果其中一条出错,后面的用例就无法执行,还有在运行大量的接口测试用 ...
- mybatis源码分析之走进缓存
之前写了一篇关于mybatis缓存的读后感,想了想还是把缓存模块简单分析一下,附赠下载地址:https://github.com/MyBatis/MyBatis-3,github直接搜排名很靠前的. ...