题目传送门

题目大意

给定一个有向图无环图\(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. gitlab启动与关闭

    gitlab安装完毕后,默认开机启动,开启关闭 sudo gitlab-ctl start/stop

  2. MySQL常用SQL 语句

    --备份数据库 mysqldump -u用户名 -h主机名 -p密码 数据库名 > filename.sql --备份数据库中的某个表 mysqldump -u用户名 -h主机名 -p密码 数据 ...

  3. 关于Linux的core dump

      core dump简介 core dump就是在进程crash时把包括内存在内的现场保留下来,以备故障分析. 但有时候,进程crash了却没有输出core,因为有一些因素会影响输出还是不输出cor ...

  4. oracle审计详解

    Oracle使用大量不同的审计方法来监控使用何种权限,以及访问哪些对象.审计不会防止使用这些权限,但可以提供有用的信息,用于揭示权限的滥用和误用. 下表中总结了Oracle数据库中不同类型的审计. 审 ...

  5. 【CF比赛记录】Codeforces Round 1013 (Div. 3)

    比赛链接 本文发布于博客园,会跟随补题进度实时更新,若您在其他平台阅读到此文,请前往博客园获取更好的阅读体验. 跳转链接:https://www.cnblogs.com/TianTianChaoFan ...

  6. Ubuntu下RabbitVCS的安装和简单使用

    最近需要在Ubuntu下玩一段时间,但是没找类似TortoiseSVN的熟悉点的Subversion工具,无意间发现了RabbitVCS,操作上非常nice,留爪. 下载 RabbitVCS Rabb ...

  7. 为什么 MySQL 选择使用 B+ 树作为索引结构?

    为什么 MySQL 选择使用 B+ 树作为索引结构? MySQL 选择 B+ 树作为其索引结构的主要原因是它具有以下几个优势,这些优势使得 B+ 树非常适合用于数据库系统中的索引实现. 1. 高效的范 ...

  8. DPDI(Dispatch PDI)kettle调度管理平台之实操演练第003讲-数据通途:客户端连接SQL Server的完美攻略

    SQL Server简介 基本概念 SQL Server是由微软公司开发的关系型数据库管理系统.它基于SQL(Structured Query Language,结构化查询语言)来管理和操作数据.SQ ...

  9. Laravel配置Route调用artisan

    //web调用artisan Route::get('/artisan', function(\Illuminate\Http\Request $request) { $all = \Illumina ...

  10. Web前端入门第 40 问:CSS float 浮动布局应用场景

    CSS float 浮动属性最早用于文字环绕图片效果,就像传统报纸上的印刷排版一样. CSS2 的规范推动了浮动用于其他元素,float 便被大范围应用于布局,当年常说的 div + css 布局,f ...