Dilworth定理:最少的下降序列个数就等于整个序列最长上升子序列的长度

概念如下:

狄尔沃斯定理_百度百科 (baidu.com)

本质就是找要求序列中最长的单调的子序列(不一定连续)的长度。


模板如下:

时间复杂度为O(N^2)

#include<iostream>using namespace std;int dp[100005],a[100005],n,maxx=-999;//dp[i]记录以i结尾的最长上升子序列int main(){cin>>n;for(int i=1;i<=n;i++) cin>>a[i],dp[i]=1;for(int i=1;i<=n;i++){for(int j=1;j<i;j++){if(a[i]>a[j]) dp[i]=max(dp[i],dp[j]+1);}maxx=max(maxx,dp[i]);                  }cout<<maxx;return 0;}

代码优化:

举个例子:

现在有序列4,8,9,5,6,7,2,7求LIS。

一个一个元素来看,首先无疑dp[1]=4 ,然后考察8,8>4,故把8加入尾部。然后9>8,也进入尾部,这时dp数组是{4, 8, 9}。

下一个元素是5,5<9,不能塞入尾部。我们找到第一个大于等于5的元素,是8。4->8是长度为2的上升子序列,4->5也是,但是5比8更小,所以更有潜力更新后面的子序列。所以把8换成5,现在DP是{4, 5, 9}。同样的道理DP又变成{4, 5, 6}。

现在我们尝到甜头了,因为下一个元素是7,本来是没有机会进入序列的,现在却可以了。于是dp变成{4, 5, 6, 7}。注意,显然DP是递增的(两种转移都不会破坏递增性),但这并不意味着它就是所求的上升子序列,你看,下一个元素是2,它会把dp更新成{2, 5, 6, 7},但原序列并没有一个子序列是{2, 5, 6, 7}。

最后剩一个元素7,由于我们在求严格上升的子序列,不能将它插入尾部,于是我们把7替换成7——这个元素对子序列长度没有贡献。好了,最后得到的数组长度是4,所以最长上升子序列的长度就是4 。

刚刚提到,dp是递增的,所以我们不用每次都扫描一遍数组, 而可以进行二分查找。这样,就把复杂度降到了 𝑂(𝑛log⁡𝑛) ,具体地,代码如下

int len = 0;
for (int i = 0; i < n; ++i)
{if (dp[len] < A[i])dp[++len] = A[i];else*lower_bound(dp + 1, dp + len + 1, A[i]) = A[i];
}

题目如下:

1、我最喜欢吃饭了

把n个人提出来成为原序列的一个子序列,根据题意这个子序列中的元素是单调递增的(即后一项总是大于前一项),我们称为单调递增子序列。本问所求n个人顺序最多需要需要多少个窗口,即求最长的单调递增子序列数目。

#include <iostream>
#include <algorithm>
using namespace std;
int a[5005], dp[5005]; int main()
{int n, m;cin >> n >> m;// n个人m个窗口for (int i = 1; i <= n; i++) cin >> a[i],dp[i] = 1; //初始化int cnt = 1;for (int i = 1; i <= n; i++){for (int j = 1; j < i; j++){if (a[i] <= a[j]) dp[i] = max(dp[i], dp[j] + 1);}cnt = max(cnt, dp[i]);}if (cnt > m)cout << "Karashi lovelove" << endl;//非法else cout << "Karashi cblcd" << endl;//合法return 0;
}

代码优化

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
int a[5005], dp[5005];int main()
{int n, m;cin >> n >> m;// n个人m个窗口for (int i = 0; i < n; i++) cin >> a[i];int len = 0;memset(dp, 127, sizeof(dp));for (int i = 0; i < n; i++){if (dp[len] >= a[i]) dp[++len] = a[i];else *upper_bound(dp + 1, dp + len + 1, a[i], greater<int>()) = a[i];}//cout << len << endl;if (len > m)cout << "Karashi lovelove" << endl;//非法else cout << "Karashi cblcd" << endl;//合法return 0;
}

2、木棍加工

思路:

1、先对宽度进行排序,然后对宽度相同的进行长度排序;大的在前,小的在后

2、然后对已经排好的数组,统计最长连续单调递减子序列数目即可。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 5010;
int f[N];struct Data
{int l, w;
}a[N];bool cmp(Data a,Data b) //先排序宽度,再排序长度
{if (a.w != b.w) return a.w > b.w;return a.l > b.l;
}int main()
{int n;cin >> n ;for (int i = 1; i <= n; i++){cin >> a[i].l >> a[i].w;f[i] = 1; //初始化}int cnt = 1;sort(a + 1, a + n + 1, cmp);for (int i = 1; i <= n; i++) //后者与前者比长度{for (int j = 1; j < i; j++){if (a[i].l > a[j].l) f[i] = max(f[i], f[j] + 1);}cnt = max(cnt, f[i]);}cout << cnt << endl;return 0;
}

3、导弹拦截

典型上述题型,但是下面会超时,因此我们要用到二分查找

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e4 + 10;
int dp1[N],a[N],dp2[N];int main()
{int n = 0;while (cin >> a[n]) {n++;}int mx1 = 0, mx2 = 0;for (int i = 0; i < n; i++){dp1[i] = 1, dp2[i] = 1;for (int j = 0; j < i; j++){if (a[j] < a[i])  dp1[i] = max(dp1[i], dp1[j] + 1);if (a[j] >= a[i]) dp2[i] = max(dp2[i], dp2[j] + 1);} mx1 = max(mx1, dp1[i]); //最长单调连续递增子序列mx2 = max(mx2, dp2[i]); //最长单调连续递减子序列}cout << mx2 << endl;cout << mx1 << endl;return 0;
}

变量声明:

数组 a 存储从输入数据;
数组 dp 存储最长不上升子序列;
变量 len 代表 dp 的结尾位置(即最长不上升子序列的长度)。


把 a 中的每个元素挨个放到 dp 里:

  • 如果 a[i] ​≤ dp​[len],说明 ai​ 可以直接加入 dp(而整个 dp 数组还是有序的);

  • 如果 a[i]​ > dp[len]​,说明若放入 a[i]​ 则 dp 会无序,所以要找办法把 a[i]​ 放进去:

怎么放呢?在 dp 中找到第一个小于 a[i]​ 的数,用 a [i]​ 代替它。
找到第一个小于 a[i]​ 的数,使用 upper_bound 可以在 O(logn) 复杂度内找到(需要改比较器)。

由于它返回的是指针就可以有一些奇特操作。

*upper_bound(dp + 1, dp + len + 1, A[i], greater<int>()) = A[i];

*lower_bound(dp + 1, dp + len + 1, a[i]) = a[i];

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 1e5 + 10;
int dp[N],a[N];int main()
{int n = 0, len = 0;while (cin >> a[n]) {n++;}memset(dp, 127, sizeof(dp));for (int i = 0; i < n; i++){if (dp[len] >= a[i]) dp[++len] = a[i];else *upper_bound(dp + 1, dp + len + 1, a[i], greater<int>()) = a[i];}cout << len << endl;len = 0;memset(dp, 0, sizeof(dp));for (int i = 0; i < n; ++i){if (dp[len] < a[i])dp[++len] = a[i];else*lower_bound(dp + 1, dp + len + 1, a[i]) = a[i];}cout << len << endl;return 0;}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12437.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

RK3568平台开发系列讲解(SPI篇)SPI数据的传输

🚀返回专栏总目录 文章目录 一、数据结构1.1、spi_transfer 结构体1.2、spi_message二、数据发送程序分析沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 参考资料: spi_transferspi_message一、数据结构 spi 数据传输主要使用了 spi_message 和 spi_transfer 结构…

二叉树的前序遍历(leetcode)

144. 二叉树的前序遍历 - 力扣&#xff08;LeetCode&#xff09; 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 这道题的启发性真的很强 &#xff0c;这里必须传入i的指针进去&#xff0c;下一次栈帧i&#xff0c;但回到了上一层i又变回到了原来的i&#…

docker network ls(用于列出 Docker 主机上的所有网络)

docker network ls 是一个 Docker 命令&#xff0c;用于列出 Docker 主机上的所有网络。Docker 允许你创建自定义的网络&#xff0c;以便更好地控制容器之间的通信。 当你运行 docker network ls 命令时&#xff0c;你可能会看到如下类似的输出&#xff08;输出可能会根据你的…

每日一题12:Pandas:数据重塑-融合

一、每日一题 解答&#xff1a; import pandas as pddef meltTable(report: pd.DataFrame) -> pd.DataFrame:reshaped_report report.melt(id_varsproduct, var_namequarter, value_namesales)return reshaped_report 题源&#xff1a;Leetcode 二、总结 melt()函数是Pa…

Nginx生产环境最佳实践之配置灰度环境

你好呀&#xff0c;我是赵兴晨&#xff0c;文科程序员。 下面的内容可以说是干货满满建议先收藏再慢慢细品。 今天&#xff0c;我想与大家深入探讨一个我们日常工作中不可或缺的话题——灰度环境。你是否在工作中使用过灰度环境&#xff1f;如果是&#xff0c;你的使用体验如…

AI图像生成-基本步骤

模型板块 1、新建采样器&#xff1a;新建节点-》采样器-》K采样器 2、拖动模型节点后放开&#xff0c;选择checkpoint加载器&#xff08;简易&#xff09;&#xff0c;模型新建成功 提示词板块 1、拖动正面条件节点后放开&#xff0c;选择CLIP文本编码器&#xff0c;模型新建…

mysql 一次删除多个备份表

show tables时&#xff0c;发现备份的表有点多&#xff0c;想要一个sql就删除 总不能drop table xx ; 写多次吧。 方式一 1.生成删除某个数据库下所有的表SQL -- 查询构建批量删除表语句&#xff08;根据数据库名称&#xff09; select concat(drop table , TABLE_NAME, ;)…

代码随想录算法训练营第39天|● 62.不同路径 ● 63. 不同路径 II

62. 不同路径 递归栈很酷 但超时 class Solution:def uniquePaths(self, m: int, n: int) -> int:if m1 or n1:return 1return self.uniquePaths(m-1,n)self.uniquePaths(m,n-1) 逐行dp class Solution:def uniquePaths(self, m: int, n: int) -> int:dp[1]*nfor j in…

FSMC的NOR Flash/PSRAM 控制器功能介绍(STM32F4)

目录 概述 1 FSMC支持的类型 1.1 信号类型概述 1.2 FSMC的应用 2 外部存储器接口信号 2.1 I/O NOR Flash 2.2 PSRAM/SRAM 3 支持的存储器和事务 4 通用时序规则 5 NOR Flash/PSRAM 控制器异步事务 5.1 模式 1 - SRAM/PSRAM (CRAM) 5.2 模式 A - SRAM/PSRAM (CRAM…

Golang | Leetcode Golang题解之第90题子集II

题目&#xff1a; 题解&#xff1a; func subsetsWithDup(nums []int) (ans [][]int) {sort.Ints(nums)n : len(nums) outer:for mask : 0; mask < 1<<n; mask {t : []int{}for i, v : range nums {if mask>>i&1 > 0 {if i > 0 && mask>&…

[HUBUCTF 2022 新生赛]ezsql

测试无结果 扫描目录&#xff0c;得到源码 找到注入点 思路&#xff1a;更新资料的时候可以同时更新所有密码 我们需要知道密码的字段名 爆库 nicknameasdf&age111,description(select database())#&descriptionaaa&token31ad6e5a2534a91ed634aca0b27c14a9 爆表…

运维别卷系列 - 云原生监控平台 之 08.prometheus grafana 实践

文章目录 [toc]部署 Grafana准备配置文件grafana.iniprovisioning/datasources/prometheus.yamlprovisioning/dashboards/dashboards.yamlprovisioning/dashboards/views 创建 svc创建 deployment Grafana 是一个图形化界面&#xff0c;配置 Prometheus 作为数据源&#xff0c;…

网络库-POCO介绍

1.简介 POCO C Libraries 提供一套 C 的类库用以开发基于网络的可移植的应用程序&#xff0c;它提供了许多模块&#xff0c;包括网络编程、文件系统访问、线程和并发、数据库访问、XML处理、配置管理、日志记录等功能。Poco库的设计目标是易于使用、高度可定制和可扩展。 包含…

Postman的简介,安装,注册。

一、安装 1.Chrome应用商品搜索Postman安装。(翻墙) 2.客户端安装官网地址:https://www.postman.com/downloads/ 3.Postman的注册和登录。 4.Postman的界面介绍 Home主页 workspaces 工作空间 Collections 集合&#xff0c;项目集合。 Apis api文档 EnViromments …

Oracle如何加密解密sha256

在Oracle数据库中&#xff0c;您可以使用内建的加密函数或者通过PL/SQL扩展来实现SHA-256加密。但请注意&#xff0c;SHA-256是一个哈希算法&#xff0c;它主要用于生成数据的哈希值&#xff0c;而不是用于加密和解密数据。哈希算法是单向的&#xff0c;即它只能从原始数据生成…

基于MSWA相继加权平均的交通流量分配算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 基于MSWA相继加权平均的交通流量分配算法matlab仿真.如图所示交通网络中&#xff0c;包含6个节点、11各路段、9个OD对。经枚举可得每个OD对间存在3条无折返有效路…

elasticsearch使用Ngram实现任意位数手机号搜索

文章目录 Ngram自定义分词案例实战问题拆解 Ngram分词器定义Ngram分词定义Ngram分词示例Ngram分词应用场景 Ngram分词实战 Ngram自定义分词案例 当对keyword类型的字段进行高亮查询时&#xff0c;若值为123asd456&#xff0c;查询sd4&#xff0c;则高亮结果是&#xff1c;em&a…

python项目连接数据库(mysql,postgresql)

在实际开发过程中&#xff0c;对于项目的数据查询和数据统计&#xff0c;那python是相当好用&#xff0c;相信很多后端工程师是java语言入门的&#xff0c;对于python呢是有一点陌生&#xff0c;我自己也是&#xff0c;不过当你操作起来呢发现其实还是蛮好上手的。以下就是一些…

C语言基础-标准库函数

C语言的标准库函数是由C语言标准库&#xff08;如C99、C11等&#xff09;提供的一系列预定义函数&#xff0c;这些函数通常用于执行常见的编程任务&#xff0c;如字符串操作、内存管理、数学计算、文件操作等。通过使用标准库函数&#xff0c;程序员可以更加高效地编写C语言程序…

在ubuntu上创建WiFi热点

要在 wlan0 无线网卡上发射热点&#xff08;即创建 WiFi 热点&#xff09;&#xff0c;可以使用 hostapd 和 dnsmasq 这两个工具。hostapd 用于创建热点&#xff0c;而 dnsmasq 用于提供 DHCP 和 DNS 服务&#xff0c;以便连接到热点的设备可以获取 IP 地址并访问互联网。 下面…