题目传送门

题目大意

给定一个有向图无环图\(G\),在这个图中寻找一条路径,是这条路径上的点权所组成的序列的最长不下降子序列的长度最长。

思路部分

解决无后效性

求一个有向无环图中的最长不下降子序列,不难想到这应该是一个图上dp,而在一个图中我们没法保证编号\(1\)到\(N\)去计算一定是满足了无后效性的,所以我们考虑找到一个顺序,这个顺序满足无后效性。

而在有向无环图中寻找一个序列,这个序列满足对于任意\(i(1≤i≤n)\),小于\(i\)的所有节点都在\(i\)的左边(或一样),大于\(i\)的所有节点都在\(i\)的右边(或一样)。

根据上述定义,不难看出这是这个有向图的拓扑序列。拓扑序的求法如下:

  1. 找到入度为\(0\)的点,入队。
  2. 重复执行直到队列为空,从队首取出一个元素\(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样题 七级] 最长不下降子序列题解的更多相关文章

  1. 网络流24题 P2766 最长不下降子序列问题

    题目描述 «问题描述: 给定正整数序列x1,...,xn . (1)计算其最长不下降子序列的长度s. (2)计算从给定的序列中最多可取出多少个长度为s的不下降子序列. (3)如果允许在取出的序列中多次 ...

  2. HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)

    6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...

  3. 【24题】P2766最长不下降子序列问题

    网络流二十四题 网络流是个好东西,希望我也会. 网络流?\(orz\ zsy!!!!!\) P2766 最长不下降子序列问题 考虑我们是如何\(dp\)这个\(LIS\)的. 我们是倒着推,设置\(d ...

  4. P2766 [网络流24题]最长不下降子序列问题

    ha~ «问题描述: 给定正整数序列$x_1,...,x_n$ .$n<=500$ 求(1)计算其最长不下降子序列的长度$s$. (2)计算从给定的序列中最多可取出多少个长度为$s$的不下降子序 ...

  5. LG2766 最长不下降子序列问题 最大流 网络流24题

    问题描述 LG2766 题解 \(\mathrm{Subtask 1}\) 一个求最长不下降子序列的问题,发现\(n \le 500\),直接\(O(n^2)\)暴力DP即可. \(\mathrm{S ...

  6. 10.26最后的模拟DAY2 改造二叉树[中序遍历+严格递增的最长不下降子序列]

    改造二叉树 [题目描述] 小Y在学树论时看到了有关二叉树的介绍:在计算机科学中,二叉树是每个结点最多有两个子结点的有序树.通常子结点被称作“左孩子”和“右孩子”.二叉树被用作二叉搜索树和二叉堆.随后他 ...

  7. 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】

    先学习下LIS最长上升子序列 ​ 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...

  8. 最长不下降子序列的O(n^2)算法和O(nlogn)算法

    一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...

  9. 最长不下降子序列nlogn算法详解

    今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子 ...

  10. SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)

    现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似, ...

随机推荐

  1. RSA密钥生成-已知p、q、e求私钥d的python脚本

    题目: 在一次RSA密钥对生成中,假设p=473398607161,q=4511491,e=17 求解出d作为flag提交 求解过程: 首先计算n和ϕ(n) n=p*q  ϕ(n)=(p-1)(q-1 ...

  2. 启动oracle 服务

    -- 参考(https://blog.csdn.net/loongshawn/article/details/51162196) 1.启动oracle的步骤 Linux下启动oracle分为以下两步: ...

  3. 【JDBC第6章】数据库事务理论

    第6章:数据库事务 6.1 数据库事务介绍 事务:一组逻辑操作单元,使数据从一种状态变换到另一种状态. 事务处理(事务操作):保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方 ...

  4. MYSQL数据库 MariaDB断电恢复总结

    背景:本次是机房异常断电,导致数据库文件损坏.在数据库自启动之后频繁宕机,在多次尝试以后,总结了一下几种方法,及供参考. 1.mariadb服务器断电重启之后Missing MLOG_CHECKPOI ...

  5. 大模型流式调用规范(SSE)

    随着大语言模型的广泛应用,如何高效地与其进行接口调用成为一个关键问题.传统的请求-响应模式在面对大模型生成大量文本时存在响应延迟高.用户体验差等问题.流式输出(Streaming)是解决该问题的重要手 ...

  6. 为什么 Java 8 移除了永久代(PermGen)并引入了元空间(Metaspace)?

    为什么 Java 8 移除了永久代(PermGen)并引入了元空间(Metaspace)? 在 Java 8 中,JVM 移除了 永久代(PermGen)并引入了 元空间(Metaspace),这一改 ...

  7. SpringBoot Task定时任务

    参数详解 @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) ...

  8. 【记录】IDA和Ollydbg查看指令地址及地址对应的指令

    文章目录 在IDA中查看指令地址 在Ollydbg中查看指令地址 在Ollydbg中查看地址对应的指令 在IDA中查看指令地址 在Ollydbg中查看指令地址 ollydbg在对应指令处,右键-查看- ...

  9. uv全功能更新:统一管理Python项目、工具、脚本和环境的终极解决方案

    花下猫语:uv 项目自发布起就大受欢迎,目前 Github star 52.6 K,远超过它的同类竞品们.前不久,它的创始人在 X 上披露了一组惊人的数据:uv 曾占据了 PyPI 超过 20% 的流 ...

  10. 智表 ZCELL 插件快速入门指南(原创)

    一.认识智表 ZCELL 插件 智表 ZCELL 是一款免费的前端 EXCEL 插件,它凝聚了多年工作经验与成果,旨在为用户带来极致的操作体验.该插件具备诸多优势,如轻量体积小,在浏览器端效率高:使用 ...