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)+前驱路径的更多相关文章

  1. LeetCode:Word Ladder I II

    其他LeetCode题目欢迎访问:LeetCode结题报告索引 LeetCode:Word Ladder Given two words (start and end), and a dictiona ...

  2. LeetCode:Word Break II(DP)

    题目地址:请戳我 这一题在leetcode前面一道题word break 的基础上用数组保存前驱路径,然后在前驱路径上用DFS可以构造所有解.但是要注意的是动态规划中要去掉前一道题的一些约束条件(具体 ...

  3. [LeetCode] Word Ladder II

    Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) from ...

  4. leecode 每日解题思路 64 Minimum Path Sum

    题目描述: 题目链接:64 Minimum Path Sum 问题是要求在一个全为正整数的 m X n 的矩阵中, 取一条从左上为起点, 走到右下为重点的路径, (前进方向只能向左或者向右),求一条所 ...

  5. Cocos2d-x 地图步行实现1:图论Dijkstra算法

    下一节<Cocos2d-x 地图行走的实现2:SPFA算法>: http://blog.csdn.net/stevenkylelee/article/details/38440663 本文 ...

  6. 【Word Ladder II】cpp

    题目: Given two words (start and end), and a dictionary, find all shortest transformation sequence(s) ...

  7. 2018.11.3 PION模拟赛

    期望:100    实际:100 #include<cstdio> #include<cstring> #include<iostream> #include< ...

  8. POJ2127 LICS模板

    题目:http://poj.org/problem?id=2127 十分费劲地终于记录好了路径……用一个前驱. 这是 n^2 的LICS方法.其实就是 n ^ 2 log n 把“找之前的d [ j ...

  9. HDU 4862 Jump(最小K路径覆盖)

    输入一个n×m网格图,每个结点的值为0-9,可以从任意点出发不超过k次,走完每个点且仅访问每个结点一次,问最终的能量最大值.不可全部走完的情况输出-1. 初始能量为0. 而结点(x,y)可以跳跃到结点 ...

随机推荐

  1. 记一次在.NET成长之路上的下午茶

    在2017年2月25日我和李海国有幸与阳铭.朱永光两位大哥喝了一次下午茶.熟悉ABP框架的朋友呢知道阳铭远在上海,所以个人很是珍惜这次机会.朱永光大哥是微软MVP,之前是启路科技的CTO,目前在微软. ...

  2. 我的AutoHotkey脚本

    #NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. ; #Warn ; En ...

  3. 如何解决jersey框架中以json格式返回数组,当数组中元素一个时json格式不对

    原文地址:http://www.cnblogs.com/swpk/p/3566536.html?utm_source=tuicool jersey 是oracle 出的一个较好的REST框架.使用此框 ...

  4. 《Linux内核设计与实现》 第五周 读书笔记(第十八章)

    第18章 调试 20135307张嘉琪 18.1 准备开始 18.2 内核中的bug 内核中的bug多种多样,它们的产生可以有无数的原因,同时它们的表象也变化多端,从明白无误的错误代码(比如,没有把正 ...

  5. <<浪潮之巅>>阅读笔记一

    第一次的阅读就想读这本书的,却因为很多愿意一直拖到现在,因为听说这本书在李开复先生 的微博上有推荐,更是增加了我的阅读兴趣.可能是因为在网上找的电子版的原因,通篇阅读的速度很快,但是没有纸质数那种细嚼 ...

  6. PAT 1047 编程团体赛

    https://pintia.cn/problem-sets/994805260223102976/problems/994805277163896832 编程团体赛的规则为:每个参赛队由若干队员组成 ...

  7. Show tree of processes in linux

    pstree(1): tree of processes - Linux man pagehttps://linux.die.net/man/1/pstree How to view process ...

  8. Spring及Spring Boot 国内快速开发框架

    http://www.javacoder.top/home.jsp# http://springboot.fun/ 一个常用的支付子项目 https://gitee.com/52itstyle/spr ...

  9. springsession 实现session 共享

    首先加入依赖1 <dependency> <groupId>org.springframework.session</groupId> <artifactId ...

  10. Wireshark协议分析工具应用

    一.Wireshark简介与安装 Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用W ...