[GESP样题 七级] 最长不下降子序列题解
题目大意
给定一个有向图无环图\(G\),在这个图中寻找一条路径,是这条路径上的点权所组成的序列的最长不下降子序列的长度最长。
思路部分
解决无后效性
求一个有向无环图中的最长不下降子序列,不难想到这应该是一个图上dp,而在一个图中我们没法保证编号\(1\)到\(N\)去计算一定是满足了无后效性的,所以我们考虑找到一个顺序,这个顺序满足无后效性。
而在有向无环图中寻找一个序列,这个序列满足对于任意\(i(1≤i≤n)\),小于\(i\)的所有节点都在\(i\)的左边(或一样),大于\(i\)的所有节点都在\(i\)的右边(或一样)。
根据上述定义,不难看出这是这个有向图的拓扑序列。拓扑序的求法如下:
- 找到入度为\(0\)的点,入队。
- 重复执行直到队列为空,从队首取出一个元素\(u\),枚举这个点能够到达的点\(v\),把点\(v\)的入度减一,判断如果点\(v\)的入度为0,那么入队。
在求拓扑序时,已经满足了无后效性这个条件,所以我们直接在这个过程中对答案求解。
解决动态规划
接着,我们讨论该如何对答案进行求解。
考虑在线性元素中对最长不下降子序列求解的定义为:以第\(i\)个元素为结尾的最长长度。那么我们是否能再次运用这个定义呢?
答案是肯定不行。第一:时间复杂度接受不了\(o(N^2)\)会炸。第二:我们无法知道以更加前面的节点为结尾的最长长度。
那么我们该如何求解呢?
根据数据范围可知,虽然点和边的数量很大,但是每个节点的点权很小,最大也就才\(10\)。所以我们可以想出以节点\(i\),点权为\(j\)结尾的最长子序列。这时,我们不需要直到之前的节点了,只需要枚举颜色是什么即可。而转移方程类似于背包,代码入下:
for(int i = 1; i <= n; i++)
if(!in[i]){//寻找入度为0的点
q.push(i);
f[i][a[i]] = 1;//对dp数组初始化
}
while(!q.empty()){//寻找拓扑序
int x = q.front(); q.pop();//队首出队
for(auto y : mp[x]){//枚举它能到达的点
for(int i = 1; i <= 10; i++){
f[y][i] = max(f[y][i], f[x][i]);//直接转移
if(a[y] >= i) //如果我的点权大于等于i,那我就可以把长度增加以(在f[x][i]的基础上)
f[y][a[y]] = max(f[y][a[y]], f[x][i] + 1);//更新
}
if(-- in[y] == 0)//寻找入度为0的点,入队
q.push(y);
}
}
这就是这个题的核心代码,读者看到这就可以自行实现一下了!但如果还是不会,那么完整代码入下。
code
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10, A = 20;
int n, m, f[N][A], ans, in[N], a[N];
vector <int> mp[N];
queue <int> q;
int main(){
scanf("%d %d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
while(m --){
int u, v; scanf("%d %d", &u, &v);
mp[u].push_back(v);
in[v] ++;
}
for(int i = 1; i <= n; i++)
if(!in[i]){
q.push(i);
f[i][a[i]] = 1;
}
while(!q.empty()){
int x = q.front(); q.pop();
for(auto y : mp[x]){
for(int i = 1; i <= 10; i++){
f[y][i] = max(f[y][i], f[x][i]);
if(a[y] >= i)
f[y][a[y]] = max(f[y][a[y]], f[x][i] + 1);
}
if(-- in[y] == 0)
q.push(y);
}
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= 10; j++)
ans = max(ans, f[i][j]);
printf("%d\n", ans);
return 0;
}
点个关注再走吧~求求了qwq
[GESP样题 七级] 最长不下降子序列题解的更多相关文章
- 网络流24题 P2766 最长不下降子序列问题
题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
- 【24题】P2766最长不下降子序列问题
网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(d ...
- P2766 [网络流24题]最长不下降子序列问题
ha~ «问题描述: 给定正整数序列$x_1,...,x_n$ .$n<=500$ 求(1)计算其最长不下降子序列的长度$s$. (2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序 ...
- LG2766 最长不下降子序列问题 最大流 网络流24题
问题描述 LG2766 题解 \(\mathrm{Subtask 1}\) 一个求最长不下降子序列的问题,发现\(n \le 500\),直接\(O(n^2)\)暴力DP即可. \(\mathrm{S ...
- 10.26最后的模拟DAY2 改造二叉树[中序遍历+严格递增的最长不下降子序列]
改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他 ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- 最长不下降子序列的O(n^2)算法和O(nlogn)算法
一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...
- 最长不下降子序列nlogn算法详解
今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子 ...
- SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)
现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似, ...
随机推荐
- gitlab启动与关闭
gitlab安装完毕后,默认开机启动,开启关闭 sudo gitlab-ctl start/stop
- MySQL常用SQL 语句
--备份数据库 mysqldump -u用户名 -h主机名 -p密码 数据库名 > filename.sql --备份数据库中的某个表 mysqldump -u用户名 -h主机名 -p密码 数据 ...
- 关于Linux的core dump
core dump简介 core dump就是在进程crash时把包括内存在内的现场保留下来,以备故障分析. 但有时候,进程crash了却没有输出core,因为有一些因素会影响输出还是不输出cor ...
- oracle审计详解
Oracle使用大量不同的审计方法来监控使用何种权限,以及访问哪些对象.审计不会防止使用这些权限,但可以提供有用的信息,用于揭示权限的滥用和误用. 下表中总结了Oracle数据库中不同类型的审计. 审 ...
- 【CF比赛记录】Codeforces Round 1013 (Div. 3)
比赛链接 本文发布于博客园,会跟随补题进度实时更新,若您在其他平台阅读到此文,请前往博客园获取更好的阅读体验. 跳转链接:https://www.cnblogs.com/TianTianChaoFan ...
- Ubuntu下RabbitVCS的安装和简单使用
最近需要在Ubuntu下玩一段时间,但是没找类似TortoiseSVN的熟悉点的Subversion工具,无意间发现了RabbitVCS,操作上非常nice,留爪. 下载 RabbitVCS Rabb ...
- 为什么 MySQL 选择使用 B+ 树作为索引结构?
为什么 MySQL 选择使用 B+ 树作为索引结构? MySQL 选择 B+ 树作为其索引结构的主要原因是它具有以下几个优势,这些优势使得 B+ 树非常适合用于数据库系统中的索引实现. 1. 高效的范 ...
- DPDI(Dispatch PDI)kettle调度管理平台之实操演练第003讲-数据通途:客户端连接SQL Server的完美攻略
SQL Server简介 基本概念 SQL Server是由微软公司开发的关系型数据库管理系统.它基于SQL(Structured Query Language,结构化查询语言)来管理和操作数据.SQ ...
- Laravel配置Route调用artisan
//web调用artisan Route::get('/artisan', function(\Illuminate\Http\Request $request) { $all = \Illumina ...
- Web前端入门第 40 问:CSS float 浮动布局应用场景
CSS float 浮动属性最早用于文字环绕图片效果,就像传统报纸上的印刷排版一样. CSS2 的规范推动了浮动用于其他元素,float 便被大范围应用于布局,当年常说的 div + css 布局,f ...