LCS(记录路径)+LIS+LCIS
https://blog.csdn.net/someone_and_anyone/article/details/81044153
当串1 和 串2 的位置i和位置j匹配成功时,
dp[i][j]=dp[i-1][j-1]+1,也就是说此状态由状态dp[i-1][j-1]转移而来,用数组记录为1,
当匹配不成功时,dp[i-1][j]和dp[i][j-1]去一个最大的,用数组分别记为2和3.
根据记录数组寻找路径:
当记录数组为1时,说明次时的i和j想等,并且此状态由i-1和j-1转移而来,所以i=i-1,j=j-1
当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由j-1转移而来,所以直接j--;
当记录数组为2时,说明此时i和j对应的数符不等,并且此状态由i-1转移而来,所以直接i--;
#include<bits/stdc++.h>
using namespace std;
const int N=+;
int dp[N][N];
int mark[N][N];
char s1[N],s2[N];
int main()
{
cin>>s1+>>s2+;
int n=strlen(s1+);
int m=strlen(s2+);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++){
if(s1[i]==s2[j]){
dp[i][j]=dp[i-][j-]+;
mark[i][j]=;
}
else if(dp[i][j-]>dp[i-][j]){
dp[i][j]=dp[i][j-];
mark[i][j]=;
}
else {
dp[i][j]=dp[i-][j];
mark[i][j]=;
}
}
string ans="";
int i=m,j=n;
while(i>&&j>){
if(mark[i][j]==) {
ans+=s1[i];
i--;j--;
}
else if(mark[i][j]==) {
j--;
}
else i--;
}
reverse(ans.begin(),ans.end());
cout<<ans<<endl; return ;
}
LIS:最长上升子序列。
O(n^2):
定义dp[i]表示考虑到第i个元素,他可以拼接到从1~i-1中比它小的元素上去。
dp[i]=max(dp[k])+1,代码比较简单,在此省略。
O(nlogn):
定义dp[len]表示当长度为len时的最小元素。
code:
dp[]=a[];
int len=;
for(int i=;i<=n;i++){
if(a[i]>dp[len]) dp[++len]=a[i];
else *lower_bound(dp+,dp++len,a[i])=a[i];
}
LCIS:最长公共上升子序列
定义状态dp[i][j]表示考虑前i个字符时,当选中第j个字符时的状态。
在这里第j个字符已经选了,所以前i个字符一定有和它匹配的,当第j个字符和第i个字符不匹配成功时,那第j个字符一定和
前i-1中的一个字符匹配喽,所以转移方程为dp[i][j]=dp[i-1][j],还是以j结尾。
当第j个字符和第i个字符匹配成功时,dp[i][j]=max(dp[i-1][k])+1,要在和前i-1个匹配的字符中选出状态最好的。
所以状态转移方程为:
dp[i][j]=dp[i-1][j],匹配成功。
dp[i][j]=max(dp[i-1][k])(k<=j)匹配不成功。
code:
void solve(int t){
ll n,m;
cin >> n;
for (ll i = ; i <= n; i++) cin >> arr[i];;
cin >> m;
for (ll i = ; i <= m; i++) cin >> brr[i];
ll mx = ;
for (ll i = ; i <= n; i++) {
mx = ;
for (ll j = ; j <= m; j++) {
dp[i][j] = dp[i - ][j];
if (brr[j] < arr[i]) mx = max(mx, dp[i-][j]);
else if (arr[i] == brr[j]) dp[i][j] = mx + ;
}
}
ll ans = ;
for (ll i = ; i <= m; i++) ans = max(ans, dp[n][i]);
cout << ans<<"\n"<<"\n";
}
一个例题:
HDU1423:Greatest Common Increasing Subsequence
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll N = 1E3 + ;
ll arr[N];
ll brr[N];
ll dp[N][N];
void solve(int t){
ll n,m;
cin >> n;
for (ll i = ; i <= n; i++) cin >> arr[i];;
cin >> m;
for (ll i = ; i <= m; i++) cin >> brr[i];
ll mx = ;
for (ll i = ; i <= n; i++) {
mx = ;
for (ll j = ; j <= m; j++) {
dp[i][j] = dp[i - ][j];
if (brr[j] < arr[i]) mx = max(mx, dp[i-][j]);
else if (arr[i] == brr[j]) dp[i][j] = mx + ;
}
}
ll ans = ;
for (ll i = ; i <= m; i++) ans = max(ans, dp[n][i]);
cout << ans<<"\n";
if(t) cout<<"\n";
}
int main(){
ll t;
cin >> t;
while (t--) solve(t);
return ;
}
LCS(记录路径)+LIS+LCIS的更多相关文章
- HDU 1503 Advanced Fruits(LCS+记录路径)
http://acm.hdu.edu.cn/showproblem.php?pid=1503 题意: 给出两个串,现在要确定一个尽量短的串,使得该串的子串包含了题目所给的两个串. 思路: 这道题目就是 ...
- LCS记录路径
还想用hash记录……果然是天真.lcs转移比较简单,每次增加1.每次找是当前-1的就行了. #include <algorithm> #include <iostream> ...
- HDU1503(LCS,记录路径)
Advanced Fruits Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)T ...
- LCS,LIS,LCIS
网站:CSUST 8月3日(LCS,LIS,LCIS) LCS: 以下讲解来自:http://blog.csdn.net/yysdsyl/article/details/4226630 [问 ...
- LCS/LIS/LCIS 模板总结
/************************* LCS/LIS/LCIs模板总结: *************************/ /*************************** ...
- 题解报告:hdu 1160 FatMouse's Speed(LIS+记录路径)
Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove th ...
- F - LCS 题解(最长公共子序列记录路径)
题目链接 题目大意 给你两个字符串,任意写出一个最长公共子序列 字符串长度小于3e3 题目思路 就是一个记录路径有一点要注意 找了好久的bug 不能直接\(dp[i][j]=dp[i-1][j-1]+ ...
- Educational DP Contest F - LCS (LCS输出路径)
题意:有两个字符串,求他们的最长公共子序列并输出. 题解:首先跑个LCS记录一下dp数组,然后根据dp数组来反着还原路径,只有当两个位置的字符相同时才输出. 代码: char s[N],t[N]; i ...
- poj1417 带权并查集 + 背包 + 记录路径
True Liars Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 2713 Accepted: 868 Descrip ...
- POJ 3436:ACM Computer Factory(最大流记录路径)
http://poj.org/problem?id=3436 题意:题意很难懂.给出P N.接下来N行代表N个机器,每一行有2*P+1个数字 第一个数代表容量,第2~P+1个数代表输入,第P+2到2* ...
随机推荐
- java基础-Map
简介 Map是一种接口,实现类有 hashMap SortedMap是继承自Map的接口,实现类为TreeMap,在内部会对Key进行排序 遍历Map 使用for each循环遍历Map实例的keyS ...
- Selenium系列(五) - 键盘操作详细解读
如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...
- hdoj 1829 A bug's life 种类并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1829 并查集的一个应用,就是检测是否存在矛盾,就是两个不该相交的集合有了交集.本题就是这样,一种虫子有 ...
- Java是如何实现自己的SPI机制的? JDK源码(一)
注:该源码分析对应JDK版本为1.8 1 引言 这是[源码笔记]的JDK源码解读的第一篇文章,本篇我们来探究Java的SPI机制的相关源码. 2 什么是SPI机制 那么,什么是SPI机制呢? SPI是 ...
- SpringBoot启动项目之后,访问页面出现Whitelabel Error Page
话说万事具备,只欠东风- 蹭闲暇时来跑个SpringBoot项目玩玩,把一切配置依赖准备就绪之后打算运行项目. Staring...... 接着,在浏览器输入地址 localhost:8080/hel ...
- 动态规划-Minimum Distance to Type a Word Using Two Fingers
2020-01-12 18:28:13 问题描述: 问题求解: 本题还是非常困难的,至少我在看到这个题目的时候是没有想到怎么解决的.我当时联想到的题目是那条grid走两遍的题目,那条题目也很麻烦,使用 ...
- 使用IDEA操作Hbase API 报错:org.apache.hadoop.hbase.client.RetriesExhaustedException的解决方法:
使用IDEA操作Hbase API 报错:org.apache.hadoop.hbase.client.RetriesExhaustedException的解决方法: 1.错误详情: Excepti ...
- 【笔记3-27】Python语言基础
流程控制语句 if语句 input() if-else if-elif-else
- 对于一个由0..n的所有数按升序组成的序列,我们要进行一些筛选,每次我们取当前所有数字中从小到大的第奇数位个的数,并将其丢弃。重复这一过程直到最后剩下一个数。请求出最后剩下的数字。
输入描述: 每组数据一行一个数字,为题目中的n(n小于等于1000). 输出描述: 一行输出最后剩下的数字.我的思路是用两个链表,一个用于存储原数据,一个用于存储要丢掉的数据,再循环从元数据中剔除掉即 ...
- 《Java多线程编程实战指南(核心篇)》阅读笔记
<Java多线程编程实战指南(核心篇)>阅读笔记 */--> <Java多线程编程实战指南(核心篇)>阅读笔记 Table of Contents 1. 线程概念 1.1 ...