题解【AcWing272】最长公共上升子序列
一道线性 DP 好题。
设 \(dp_{i,j}\) 表示在所有 \(a_{1\dots i}\),\(b_{1\dots j}\) 的子序列中,以 \(b_j\) 结尾的最长公共上升子序列的最大长度。
转移的时候考虑 \(2\) 种情况:
- 若不选择 \(a_i\),则 \(dp_{i,j}=dp_{i-1,j}\);
- 若选择 \(a_i\),则 \(dp_{i,j} = \max_{1\leq k \leq j,b_k < b_j}\{dp_{i-1,k}\}+1\)。又因为有 \(a_i=b_j\),所以 \(dp_{i,j} = \max_{1\leq k \leq j,b_k < a_i}\{dp_{i-1,k}\}+1\)。
转移的代码:
for (int i = 1; i <= n; i+=1)
for (int j = 1; j <= n; j+=1)
{
dp[i][j] = dp[i - 1][j];
if (a[i] == b[j])
{
int maxdp = 0;
for (int k = 1; k < j; k+=1)
if (b[k] < a[i])
maxdp = max(maxdp, dp[i - 1][k]);
dp[i][j] = max(dp[i][j], maxdp + 1);
}
}
这样转移的复杂度其实是 \(O(n^3)\) 的,明显会超时。
于是我们考虑优化,即对转移的代码进行等价变形。
我们发现,第三重循环能够转移的状态其实是所有 小于 \(j\) 的 \(k\),且 \(b_k < a_i\)。因为 \(a_i\) 的值是不变的,所以我们可以预处理出所有 \(dp_{i,k}(k<j)\) 的最大值,即 \(dp_{i,j}\) 的前缀最大值。
具体做法就是将变量 maxdp 移到第二层循环外,然后如果 \(b_j < a_i\) 就将 maxdp 与 \(dp_{i,j}\) 取 \(\max\)。
完整代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 3003;
int n, m;
int a[N], b[N], dp[N][N];
int main()
{
cin >> n;
for (int i = 1; i <= n; i+=1)
cin >> a[i];
for (int i = 1; i <= n; i+=1)
cin >> b[i];
for (int i = 1; i <= n; i+=1)
{
int maxdp = 0;
for (int j = 1; j <= n; j+=1)
{
dp[i][j] = dp[i - 1][j];
if (a[i] == b[j]) dp[i][j] = max(dp[i][j], maxdp + 1); //转移
if (b[j] < a[i]) maxdp = max(maxdp, dp[i][j]); //前缀最大值
}
}
int ans = 1;
for (int i = 1; i <= n; i+=1) ans = max(ans, dp[n][i]);
cout << ans << endl;
return 0;
}
题解【AcWing272】最长公共上升子序列的更多相关文章
- Acwing272 最长公共上升子序列
题目大意:给定两个大小为n的数组,让你找出最长公共上升子序列的长度. 分析:这是一个比较好的dp题,LIS和LCS两大经典线性dp问题相结合,简称LCIS. 代码(O(n*n*n)写法): #incl ...
- CH5101 LCIS(最长公共上升子序列) 题解
每日一题 day16 打卡 Analysis 设F[i,j]表示A[1..i]与B[1..j]并且以B[j]结尾的两段最长公共上升子序列,那么我们可以发现这样的转移 (1)A[i]==B[j]时 F[ ...
- 最长公共上升子序列(codevs 2185)
题目描述 Description 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序列了. 小沐沐说,对 ...
- codevs 2185 最长公共上升子序列
题目链接: codevs 2185 最长公共上升子序列codevs 1408 最长公共子序列 题目描述 Description熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升 ...
- [codevs2185]最长公共上升子序列
[codevs2185]最长公共上升子序列 试题描述 熊大妈的奶牛在小沐沐的熏陶下开始研究信息题目.小沐沐先让奶牛研究了最长上升子序列,再让他们研究了最长公共子序列,现在又让他们要研究最长公共上升子序 ...
- hdu1423 最长公共上升子序列
题目传送门 Greatest Common Increasing Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- CF10D LCIS 最长公共上升子序列
题目描述 This problem differs from one which was on the online contest. The sequence a1,a2,...,an a_{1}, ...
- 最长公共上升子序列(LCIS)
最长公共上升子序列慕名而知是两个字符串a,b的最长公共递增序列,不一定非得是连续的.刚开始看到的时候想的是先用求最长公共子序列,然后再从其中找到最长递增子序列,可是仔细想一想觉得这样有点不妥,然后从网 ...
- ZOJ 2432 Greatest Common Increasing Subsequence(最长公共上升子序列+路径打印)
Greatest Common Increasing Subsequence 题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problem ...
随机推荐
- abp(net core)+easyui+efcore实现仓储管理系统——入库管理之一(三十七)
abp(net core)+easyui+efcore实现仓储管理系统目录 abp(net core)+easyui+efcore实现仓储管理系统——ABP总体介绍(一) abp(net core)+ ...
- Python Special Methods - 特殊方法
特殊方法 特殊方法的存在是为了给 Python 解释器调用的,通常自己并不需要直接调用它们.也就是说不应该使用 my_object.__len__() 这种写法,而应该使用 len(my_object ...
- iOS - 一个简单的带标题的图标的实现
代码不复杂,直接上代码: ImageViewButton.h // // ImageViewButton.h// // 带有图片.底部标题或者顶部的按钮 // // #import <UIKit ...
- Apache开启GZIP 压缩网页
首先我们先了解Apache Gzip的相关资料. 一.gzip介绍 Gzip是一种流行的文件压缩算法,现在的应用十分广泛,尤其是在Linux平台.当应用Gzip压缩到一个纯文本文件时,效果是非常明显的 ...
- post 两种方式 application/x-www-form-urlencoded和multipart/form-data
本次主要涉及 application/x-www-form-urlencoded方式. postman访问方式如图: java代码实现: 首先使用maven作为第三方依赖管理: <depende ...
- JAVA架构之单点登录 任务调度 权限管理 性能优化大型项目实战
单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任.单点登录在大型网站里使用得 ...
- 01、Git安装教程(windows)
首先如下图:(点击next) 第二步:文件位置存储,可根据自己盘的情况安装 第三步:安装配置文件,自己需要的都选上,下一步 第四步:不创建启动文件夹,下一步: 第五步:选择默认的编辑器,我们直接用推荐 ...
- DOTNET Core MVC (一)
以控台的形式,运行.net core mvc 代码, Host.CreateDefaultBuilder(args) .ConfigureWebHostDefaults(webBuilder => ...
- Kotlin Tutorials系列文章
Kotlin Tutorials系列文章 想写一个有实用价值的Kotlin笔记, 让一线开发一看就懂, 看完就能上手. 当然官方文档更有参考价值了. 这个系列相对于官方文档的大而全来说, 最主要优势是 ...
- 史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点
史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点 1