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--;

例题:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int N=+;
  4. int dp[N][N];
  5. int mark[N][N];
  6. char s1[N],s2[N];
  7. int main()
  8. {
  9. cin>>s1+>>s2+;
  10. int n=strlen(s1+);
  11. int m=strlen(s2+);
  12. for(int i=;i<=n;i++)
  13. for(int j=;j<=m;j++){
  14. if(s1[i]==s2[j]){
  15. dp[i][j]=dp[i-][j-]+;
  16. mark[i][j]=;
  17. }
  18. else if(dp[i][j-]>dp[i-][j]){
  19. dp[i][j]=dp[i][j-];
  20. mark[i][j]=;
  21. }
  22. else {
  23. dp[i][j]=dp[i-][j];
  24. mark[i][j]=;
  25. }
  26. }
  27. string ans="";
  28. int i=m,j=n;
  29. while(i>&&j>){
  30. if(mark[i][j]==) {
  31. ans+=s1[i];
  32. i--;j--;
  33. }
  34. else if(mark[i][j]==) {
  35. j--;
  36. }
  37. else i--;
  38. }
  39. reverse(ans.begin(),ans.end());
  40. cout<<ans<<endl;
  41.  
  42. return ;
  43. }

LIS:最长上升子序列。

O(n^2):

  定义dp[i]表示考虑到第i个元素,他可以拼接到从1~i-1中比它小的元素上去。

  dp[i]=max(dp[k])+1,代码比较简单,在此省略。

O(nlogn):

  定义dp[len]表示当长度为len时的最小元素。

code:

  

  1. dp[]=a[];
  2. int len=;
  3. for(int i=;i<=n;i++){
  4. if(a[i]>dp[len]) dp[++len]=a[i];
  5. else *lower_bound(dp+,dp++len,a[i])=a[i];
  6. }

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:

  1. void solve(int t){
  2. ll n,m;
  3. cin >> n;
  4. for (ll i = ; i <= n; i++) cin >> arr[i];;
  5. cin >> m;
  6. for (ll i = ; i <= m; i++) cin >> brr[i];
  7. ll mx = ;
  8. for (ll i = ; i <= n; i++) {
  9. mx = ;
  10. for (ll j = ; j <= m; j++) {
  11. dp[i][j] = dp[i - ][j];
  12. if (brr[j] < arr[i]) mx = max(mx, dp[i-][j]);
  13. else if (arr[i] == brr[j]) dp[i][j] = mx + ;
  14. }
  15. }
  16. ll ans = ;
  17. for (ll i = ; i <= m; i++) ans = max(ans, dp[n][i]);
  18. cout << ans<<"\n"<<"\n";
  19. }

一个例题:

HDU1423:Greatest Common Increasing Subsequence

code:

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. using namespace std;
  5. typedef long long ll;
  6. const ll N = 1E3 + ;
  7. ll arr[N];
  8. ll brr[N];
  9. ll dp[N][N];
  10. void solve(int t){
  11. ll n,m;
  12. cin >> n;
  13. for (ll i = ; i <= n; i++) cin >> arr[i];;
  14. cin >> m;
  15. for (ll i = ; i <= m; i++) cin >> brr[i];
  16. ll mx = ;
  17. for (ll i = ; i <= n; i++) {
  18. mx = ;
  19. for (ll j = ; j <= m; j++) {
  20. dp[i][j] = dp[i - ][j];
  21. if (brr[j] < arr[i]) mx = max(mx, dp[i-][j]);
  22. else if (arr[i] == brr[j]) dp[i][j] = mx + ;
  23. }
  24. }
  25. ll ans = ;
  26. for (ll i = ; i <= m; i++) ans = max(ans, dp[n][i]);
  27. cout << ans<<"\n";
  28. if(t) cout<<"\n";
  29. }
  30. int main(){
  31. ll t;
  32. cin >> t;
  33. while (t--) solve(t);
  34. return ;
  35. }

LCS(记录路径)+LIS+LCIS的更多相关文章

  1. HDU 1503 Advanced Fruits(LCS+记录路径)

    http://acm.hdu.edu.cn/showproblem.php?pid=1503 题意: 给出两个串,现在要确定一个尽量短的串,使得该串的子串包含了题目所给的两个串. 思路: 这道题目就是 ...

  2. LCS记录路径

    还想用hash记录……果然是天真.lcs转移比较简单,每次增加1.每次找是当前-1的就行了. #include <algorithm> #include <iostream> ...

  3. HDU1503(LCS,记录路径)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  4. LCS,LIS,LCIS

    网站:CSUST 8月3日(LCS,LIS,LCIS) LCS:      以下讲解来自:http://blog.csdn.net/yysdsyl/article/details/4226630 [问 ...

  5. LCS/LIS/LCIS 模板总结

    /************************* LCS/LIS/LCIs模板总结: *************************/ /*************************** ...

  6. 题解报告:hdu 1160 FatMouse's Speed(LIS+记录路径)

    Problem Description FatMouse believes that the fatter a mouse is, the faster it runs. To disprove th ...

  7. F - LCS 题解(最长公共子序列记录路径)

    题目链接 题目大意 给你两个字符串,任意写出一个最长公共子序列 字符串长度小于3e3 题目思路 就是一个记录路径有一点要注意 找了好久的bug 不能直接\(dp[i][j]=dp[i-1][j-1]+ ...

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

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

  9. poj1417 带权并查集 + 背包 + 记录路径

    True Liars Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2713   Accepted: 868 Descrip ...

  10. POJ 3436:ACM Computer Factory(最大流记录路径)

    http://poj.org/problem?id=3436 题意:题意很难懂.给出P N.接下来N行代表N个机器,每一行有2*P+1个数字 第一个数代表容量,第2~P+1个数代表输入,第P+2到2* ...

随机推荐

  1. P4147 玉蟾宫 题解

    原题链接 简要题意: 求最大 \(0\) 矩阵.(将字符转化为数字) 本题是模板题,可以用来爆踩.??? 悬线法 来了! 其中绿色是 \(0\),红色是 \(1\). 下面以这个图为例讲一下算法流程. ...

  2. nmap端口扫描工具安装和使用方法

    nmap(Network Mapper)是一款开源免费的针对大型网络的端口扫描工具,nmap可以检测目标主机是否在线.主机端口开放情况.检测主机运行的服务类型及版本信息.检测操作系统与设备类型等信息. ...

  3. 贪心-谷歌-857. 雇佣 K 名工人的最低成本

    2020-03-15 22:00:39 问题描述: 有 N 名工人. 第 i 名工人的工作质量为 quality[i] ,其最低期望工资为 wage[i] . 现在我们想雇佣 K 名工人组成一个工资组 ...

  4. 「面试指南」JS数组Array常用算法,Array算法的一般解答思路

    先看一道面试题 在 LeetCode 中有这么一道简单的数组算法题: // 给定一个整数数组 nums 和一个目标值 target, // 请你在该数组中找出和为目标值的那两个整数,并返回他们的数组下 ...

  5. Linux中cache和buff的区别

    两者都是:缓冲区 cache是存在于cpu和内存之间的缓冲区,存放的是从disk上读取到的数据 buff是用于存放要输出到块存储的数据 清除缓冲的方法 [root@DD-Server-9F ~]# e ...

  6. 1+1>2:MIT&IBM提出结合符号主义和连接主义的高效、准确新模型

    自人工智能的概念提出以来,关于符号主义和连接主义的争论就不绝于耳.究竟哪一种方式可以实现更好的人工智能?这一问题目前还没有定论.深度学习的快速发展让我们看到连接主义在构建 AI 系统中的优势,但其劣势 ...

  7. POJ - 1061 青蛙的约会 扩展欧几里得 + (贝祖公式)最小正整数解

    题意: 青蛙 A 和 青蛙 B ,在同一纬度按照相同方向跳跃相同步数,A的起点为X ,每一步距离为m,B的起点为Y,每一步距离为 n,一圈的长度为L,求最小跳跃步数. 思路: 一开始按照追击问题来写, ...

  8. 不可思议的hexo,五分钟教你免费搭一个高逼格技术博客

    引言 作为程序员拥有一个属于自己的个人技术博客,绝对是百利无一害的事,不仅方便出门装b,面试时亮出博客地址也会让面试官对你的好感度倍增.经常能在很多大佬的技术文章的文末,看到这样一句话: " ...

  9. 在Centos7下搭建大数据环境,即Zookeeper+Hadoop+HBase

    1. 所需软件下载链接(建议直接复制链接到迅雷下载更快): ①hadoop-2.7.6.tar.gz: wget http://mirrors.tuna.tsinghua.edu.cn/apache/ ...

  10. 有效括号算法题(Golang实现)

    有效括号算法题 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合.左括号必须以正确的顺序闭合.注意空 ...