LICS O(n*m)+前驱路径
LICS:最长公共上升子序列;
一般令f[i][j]表示a串前i位,b串以j结尾的LICS长度。于是,答案为:max(1~m)(f[n][i]);
朴素做法:O(n^3) 相等时,从1~j-1枚举最大值。
- for(int i=;i<=n;i++)
- for(int j=;j<=m;j++)
- {if(a[i]!=b[j]) f[i][j]=f[i-][j];
- else if(a[i]==b[j])
- for(int k=;k<j;k++)
- if(b[k]<b[j]) f[i][j]=f[i-][k];
- }
算法时间复杂度改进思路主要从优化第三层(k)复杂度入手。
升级做法: O(n^2logn) 利用树状数组记录f[i-1][1~j-1]最大值; 数组下表记录的是b串数值。 (第一个j循环预处理,并且更新上一次的成果)需要:树状数组和离散化。
- int mx[]
- for(int i=;i<=n;i++)
- {
- for(int j=;j<=m;j++)
- {mx[j]=query(b[j]-)//0~b[j]-1 这些数中的f最大值
- modify(b[j],f[i-][j])//将上一轮求出的f尝试更新
- }
- for(int j=;j<=m;j++)
- if(a[i]==b[j]) f[i][j]=mx[j]+;
- else f[i][j]=f[i-][j];
- }
其实这样很麻烦。 复杂度中等,还需要离散化,求具体子序列还要还原。
终极做法:O(n^2) 考虑到,每次进行j循环时,i不动,a[i]的值暂时不变。所以只需边求边记录最大值即可。 直接省掉k层循环。
- for(int i=;i<=n;i++)
- {
- int mx=f[i-][];
- for(int j=;j<=m;j++)
- if(a[i]!=a[j])
- f[i][j]=f[i-][j]
- else
- f[i][j]=mx+;
- if(b[j]<a[i])//j即将变成j+1,尝试更新mx(只有b[j]<a[i]才可以保证上升)
- mx=max(mx,f[i-1][j])
- }
poj 2127 至于要求具体子序列时,需要记录使之更新的前驱,即path[i][j]=某个位置bj; 因为是“以j结尾”,所以记录bj。输出时输出b[bj];
详见代码: ai,aj记录使答案成为ans的第一个位置。 故可以直接输出b[aj];
- #include<cstdio>
- #include<cstdlib>
- #include<iostream>
- using namespace std;
- const int N=;
- int f[N][N],path[N][N];
- int mj,mx,sum,ai,aj;
- int ans[N];
- int n,m;
- int a[N],b[N];
- int main()
- {
- scanf("%d",&n);
- for(int i=;i<=n;i++)
- scanf("%d",&a[i]);
- scanf("%d",&m);
- for(int i=;i<=m;i++)
- scanf("%d",&b[i]);
- for(int i=;i<=n;i++)
- {
- mx=;
- for(int j=;j<=m;j++)
- {
- f[i][j]=f[i-][j];
- path[i][j]=-;
- if(b[j]<a[i]&&f[i-][j]>mx)
- {
- mx=f[i-][j];
- mj=j;
- }
- else if(a[i]==b[j])
- {
- f[i][j]=mx+;
- path[i][j]=mj;
- }
- if(sum<f[i][j])
- {
- sum=f[i][j];
- ai=i;
- aj=j;
- }
- }
- }
- printf("%d\n",sum);
- int tmp=sum;
- while(tmp)
- {
- if(path[ai][aj]>-)
- {
- ans[tmp--]=b[aj];
- aj=path[ai][aj];
- }
- ai--;
- }
- for(int i=;i<=sum;i++)
- printf("%d ",ans[i]);
- return ;
- }
纯手打。 参考:https://www.cnblogs.com/dream-wind/archive/2012/08/25/2655641.html
LICS O(n*m)+前驱路径的更多相关文章
- LeetCode:Word Ladder I II
其他LeetCode题目欢迎访问:LeetCode结题报告索引 LeetCode:Word Ladder Given two words (start and end), and a dictiona ...
- LeetCode:Word Break II(DP)
题目地址:请戳我 这一题在leetcode前面一道题word break 的基础上用数组保存前驱路径,然后在前驱路径上用DFS可以构造所有解.但是要注意的是动态规划中要去掉前一道题的一些约束条件(具体 ...
- [LeetCode] Word Ladder II
Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...
- leecode 每日解题思路 64 Minimum Path Sum
题目描述: 题目链接:64 Minimum Path Sum 问题是要求在一个全为正整数的 m X n 的矩阵中, 取一条从左上为起点, 走到右下为重点的路径, (前进方向只能向左或者向右),求一条所 ...
- Cocos2d-x 地图步行实现1:图论Dijkstra算法
下一节<Cocos2d-x 地图行走的实现2:SPFA算法>: http://blog.csdn.net/stevenkylelee/article/details/38440663 本文 ...
- 【Word Ladder II】cpp
题目: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) ...
- 2018.11.3 PION模拟赛
期望:100 实际:100 #include<cstdio> #include<cstring> #include<iostream> #include< ...
- POJ2127 LICS模板
题目:http://poj.org/problem?id=2127 十分费劲地终于记录好了路径……用一个前驱. 这是 n^2 的LICS方法.其实就是 n ^ 2 log n 把“找之前的d [ j ...
- HDU 4862 Jump(最小K路径覆盖)
输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...
随机推荐
- 过渡与动画 - 缓动效果&基于贝塞尔曲线的调速函数
难题 给过渡和动画加上缓动效果是一种常见的手法(比如具有回弹效果的过渡过程)是一种流行的表现手法,可以让界面显得更加生动和真实:在现实世界中,物体A点到B点往往也是不完全匀速的 以纯技术的角度来看,回 ...
- ubuntu16.04在GTX1070环境下安装 cuda9.1
设备要求 系统:Ubuntu16.04 显卡:GTX 1070 驱动:nvidia系列,显卡驱动的版本必须大于等于cuda的sh文件名里面的版本号 驱动可从 此处 下载,我已经整理好了 检查安装驱动 ...
- PHP 文件写入和读取(必看篇)
文章提纲: 一.实现文件读取和写入的基本思路 二.使用fopen方法打开文件 三.文件读取和文件写入操作 四.使用fclose方法关闭文件 五.文件指针的移动 六.Windows和UNIX下的回车和换 ...
- 剑指offer:二叉树中和为某一值的路径
本来这只是一个普通的算法题,但是当初自己OJ上提交时,总是提交失败,而我自己认定程序逻辑没有任何问题.然后开始就在本机上调试,结果发现这是由于Python的对象机制而引发的.所以先把问题算法题贴出来, ...
- python 中的列表(list)
一.生成一个列表 直接生成 L1 = [1, 2, 3, 4, 5] 列表解析式 >>> L2 = [x for x in range(1, 10, 2)] #从1到10的迭代,步长 ...
- HDU 2052 Picture
http://acm.hdu.edu.cn/showproblem.php?pid=2052 Problem Description Give you the width and height of ...
- What is the difference between apache tomcat deployer and core version? - Stack Overflow
java - What is the difference between apache tomcat deployer and core version? - Stack Overflowhttps ...
- activiti engine.schema.update DB_SCHEMA_UPDATE_FALSE
engine.properties # engine propertiesengine.schema.update=trueengine.activate.jobexecutor=falseengin ...
- Activiti中子流程:SubProcess,CallActiviti的区别
子流程:SubProcess,CallActiviti的区别 https://community.alfresco.com/thread/221771-call-activiti-vs-subproc ...
- Jfrog Artifactory 创建docker 镜像仓库以及 push 镜像到 该仓库.
1. 安装aitifactory 以及 启动 使用30天有效期激活 不在阐述. 2. 登录artifactory username:admin password:password 3. 创建 仓库 在 ...