【算法】dp题单
题单链接: https://vjudge.net/contest/574209#overview
目录
1. 洛谷 P1020 导弹拦截 (dp+二分+Dilworth 定理)
2. P1439 最长公共子序列(二分求最长公共子序列)
3. 洛谷 P1854 花店橱窗布置 (线性dp + 用pre数组记录路径)
1. 洛谷 P1020 导弹拦截 (dp+二分+Dilworth 定理)
题目: https://www.luogu.com.cn/problem/P1020
思想:第一问是求最长不上升子序列,即后一项小于等于前一项,由于数据1e5,考虑二分。
首先把当前项小于等于前一项的加入 f 数组,如果当前项大于 f 数组前一项,那么向前找 f 数组的第一项小于当前项的下标,并用当前值代替二分找到的这个数。
第二问是求不上升子序列的个数,根据Dilworth 定理,一个序列若干个单调不升子序列的最小个数等于该序列最长上升子序列的个数,可以知这题求最长上升子序列的个数。首先把当前值大于 f 数组前一项的值加入 f 数组。如果小等于,那么找到 f 数组第一个大于等于当前值的项(为什么是大于等于,而不是大于,因为最长上升子序列要满足严格大于,所以等于的情况也需要被替代),并用当前值代替二分找到的这个值。
考虑一个数列5 2 3 1 4
首先,把5加入答案序列中,然后加2,发现2<5所以显然2替换5不会使结果更差,
那么答案序列就是{2},然后加3,发现3>2,所以直接把3加到答案序列中:{2,3}
然后加1,我们发现1<3,于是我们找到一个最小的但是比1大的数字2,然后把1替换2,为什么这么做不会影响结果呢?你可以这么想,我们当前已经求出了一个当前最优的序列,如果我们用1替换2,然后后面来一个数字替换了3,那么我们就可以得到一个更优的序列,而如果没有数字替换3,那么这个1替换2也就是没有贡献的,不会影响我们结果的最优性。至于,如何找到一个最小的但是大于某个数字的数字,弄个二分查找就行了,因为我们的答案序列是有序的呀。
代码:
// Problem: B - 导弹拦截
// Contest: Virtual Judge - CQJTU-DP题单1——线性DP
// URL: https://vjudge.net/contest/574209#problem/B
// Memory Limit: 131 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include<bits/stdc++.h>
using namespace std;typedef long long ll;const int N = 2e5+5;
const int inf = 0x3f3f3f3f;int a[N];
int f[N];int main(){ios::sync_with_stdio(false);cin.tie(nullptr);int x=0;int n=0;while(cin>>x){ a[++n]=x;}memset(f,0,sizeof(f));f[0]=1e9; int cnt=0; for(int i=1;i<=n;i++){if(a[i]<=f[cnt]){ //得到不递增的数组f[++cnt]=a[i]; }else{ int l=1,r=cnt; //找到第一个小于当前导弹高度的元素位置,将其更新为导弹高度while(l<r){int mid=(l+r)/2;if(f[mid]<a[i]){r=mid;}else l=mid+1;}f[l]=a[i];}/*for(int i=1;i<=cnt;i++){cout<<f[i]<<' ';}cout<<"\n";*/}cout<<cnt<<"\n";cnt=0;memset(f,0,sizeof(f));for(int i=1;i<=n;i++){if(a[i]>f[cnt]){ //找到递增数组f[++cnt]=a[i];}else{int l=1,r=cnt;while(l<r){ //找到第一个大于等于当前导弹高度的导弹位置,将其更新为导弹高度int mid=(l+r)/2;if(f[mid]>=a[i]){r=mid;}else l=mid+1;}f[l]=a[i];}/*for(int i=1;i<=cnt;i++){cout<<f[i]<<' ';}cout<<"\n";*/}cout<<cnt<<"\n";return 0; }
2. P1439 最长公共子序列(二分求最长公共子序列)
题目: https://www.luogu.com.cn/problem/P1439
思想:
首先,我们可以想到,最长公共子序列,就是两段所含数字完全一样,并且数字的顺序也是完全一样的序列。
而顺序,我们可以想到类似哈希的思想,考虑建立一个类似map的关系数组f[ai]=i,那么我们找到的序列只要是上升的,顺序就是一样的,然后考虑数字完全一样,由于我们已经有了一个f[ai]=i,所以我们把对应的bi改成f[bi],就可以确保数字相等了呀!
这时,就是在f[bi]的数组中求个最长上升子序列了,二分搞一搞就好了。STL大法好!
代码:
// Problem: C - 最长公共子序列
// Contest: Virtual Judge - CQJTU-DP题单1——线性DP
// URL: https://vjudge.net/contest/574209#problem/C
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include<bits/stdc++.h>
using namespace std;typedef long long ll;const int N = 2e5+5;
const int inf = 0x3f3f3f3f;int n;
int a[N],b[N];
int f[N];int main(){ios::sync_with_stdio(false);cin.tie(nullptr);cin>>n;map<int,int> mp;for(int i=1;i<=n;i++){cin>>a[i];mp[a[i]]=i;}for(int i=1;i<=n;i++){cin>>b[i];//cout<<mp[b[i]]<<' ';}//cout<<"\n";//mp[b[i]]可以表示a数组中的每个数在b中的位置保证数字一样//然后找最长上升子序列保证顺序一样memset(f,127,sizeof(f));f[0]=0;int cnt=0;for(int i=1;i<=n;i++){if(mp[b[i]]>f[cnt]){ //找到b数组的最长上升子序列f[++cnt]=mp[b[i]];}else{int l=0,r=cnt;while(l<r){int mid=(l+r)/2;if(f[mid]>mp[b[i]]){r=mid;}else l=mid+1;}f[l]=min(mp[b[i]],f[l]);}/*for(int i=1;i<=cnt;i++){cout<<mp[i]<<' ';}cout<<"\n";*/}cout<<cnt<<"\n";return 0; }
3. 洛谷 P1854 花店橱窗布置 (线性dp + 用pre数组记录路径)
题目: https://www.luogu.com.cn/problem/P1854
思想:用 k 遍历 j 找到这一行最大的值,并且用 pre 数组记录当前点前一个位置为 k ,即上一行最大值的位置,结果最大值需要遍历最后一行每一列的值,而不是 f[n][m],然后以这个点往前找
pre数组 ,用pos数组存下每一行的值,最后输出。 pos[i-1] = pre[i][pos[i]]
代码:
// Problem: E - 花店橱窗布置
// Contest: Virtual Judge - CQJTU-DP题单1——线性DP
// URL: https://vjudge.net/contest/574209#problem/E
// Memory Limit: 128 MB
// Time Limit: 1000 ms
//
// Powered by CP Editor (https://cpeditor.org)#include<bits/stdc++.h>
using namespace std;typedef long long ll;const int N = 1001;
const int inf = 0x3f3f3f3f;int n,m;
int a[N][N];
int f[N][N];
int pre[N][N];
int pos[N];int main(){ios::sync_with_stdio(false);cin.tie(nullptr);cin>>n>>m;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){cin>>a[i][j];}}for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){f[i][j]=-inf;}}memset(pre,0,sizeof(pre));/*for(int i=1;i<=n;i++){f[0][i]=0;}*/for(int i=1;i<=n;i++){f[0][i]=0;for(int j=i;j<=m;j++){for(int k=i-1;k<j;k++){if(f[i-1][k]+a[i][j]>f[i][j]){f[i][j]=f[i-1][k]+a[i][j];pre[i][j]=k;}}}}int maxv=-inf;for(int i=1;i<=m;i++){if(f[n][i]>maxv){pos[n]=i;maxv=f[n][i];}}cout<<maxv<<"\n";for(int i=n;pre[i][pos[i]]!=0;i--){pos[i-1]=pre[i][pos[i]];}for(int i=1;i<=n;i++){cout<<pos[i]<<' ';}cout<<"\n";return 0; }
相关文章:
【算法】dp题单
题单链接: https://vjudge.net/contest/574209#overview 目录 1. 洛谷 P1020 导弹拦截 (dp二分Dilworth 定理) 2. P1439 最长公共子序列(二分求最长公共子序列) 3. 洛谷 P1854 花店橱窗布置 (线性dp 用…...
Verilog视频信号图形显示 FPGA(iCE40)
您需要一块带视频输出的 FPGA 板。 我们将在 640x480 下工作,几乎任何视频输出都可以在此像素工作。 它有助于轻松地对 FPGA 板进行编程并相当熟悉 Verilog。 如果您没有开发板,请不要担心,您可以使用 Verilator 模拟器。 材料 Lattice iCE…...
【LeetCode 面试经典150题】26. Remove Duplicates from Sorted Array 在有序数组中移除重复元素
26. Remove Duplicates from Sorted Array 题目大意 Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appears only once. The relative order of the elements should be kept the same. Then …...

linux系统下sql脚本的执行与导出
terminal中执行 执行 mysql -u [username] -p -D [databasename] < [XXX.sql] 导出 mysql -u [username] -p [datbasename] > [XXX.sql] 导出的数据库名自定义。 mysql -u [username] -p [databasename] [tablename] > [xxx.sql] 导出表名自定义 mysql shell 执行 …...

MyBatis学习一:快速入门
前言 公司要求没办法,前端也要了解一下后端知识,这里记录一下自己的学习 学习教程:黑马mybatis教程全套视频教程,2天Mybatis框架从入门到精通 文档: https://mybatis.net.cn/index.html MyBatis 快速入门…...

零售业物流这个防漏水技术,居然没有翻车!
随着科技的不断发展,水浸监控系统在各个领域得到了广泛应用。水浸监控不仅仅是为了保护建筑结构和设备,更是为了防范因水灾引起的生命安全和财产损失。 因此,为了有效预防和应对水浸事件,水浸监控系统应运而生,成为各行…...

主浏览器优化之路1——你现在在用的是什么浏览器?Edge?谷歌?火狐?360!?
上一世,我的浏览器之路 引言为什么要用两个浏览器为什么一定要放弃火狐结尾给大家一个猜数字小游戏(测运气) 引言 小时候,我一开始上网的浏览器是2345王牌浏览器吧, 因为上面集成了很多网站,我记得上面有7…...

gitlab请求合并分支
直接去看原文: 原文链接:Gitlab合并请求相关流程_source branch target branch-CSDN博客 --------------------------------------------------------------------------------------------------------------------------------- 入口: 仓库控制台的这两个地方都…...

使用Vue3开发学生管理系统模板1
环境搭建 通过解压之前《Vue3开发后台管理系统模板》的代码,我们能够得到用户增删改查的页面,我们基于用户增删改查的页面做进一步的优化。 创建学生增删改查页面 第一步:复制用户增删改查页面,重命名为StudentCRUD.vue <…...

【cmake实战:番外】交叉编译——Linaro
【cmake实战:番外】交叉编译——Linaro 一、交叉编译1、交叉编译简介2、为什么会有交叉编译 二、交叉编译链1、什么是交叉编译链2、交叉编译工具 三、Linaro1、下载2、解压3、demo3.1、toolchain_aarch64.cmake3.2、CMakeLists.txt3.3、main.cpp 4、执行编译5、查看…...
2024年年初Java5年实战面试题(北京)
高阶篇: 一、在面对千万条并发请求的情况下,如果数据库频繁查询导致崩溃,可以采取以下措施来解决问题: 1.缓存数据:可以使用缓存技术来减少对数据库的查询次数。将经常查询的数据存储在缓存中,例如使用Redis等内存数据库ÿ…...

【Apache-2.0】springboot-openai-chatgpt超级AI大脑产品架构图
springboot-openai-chatgpt: 一个基于SpringCloud的Chatgpt机器人,已对接GPT-3.5、GPT-4.0、百度文心一言、stable diffusion AI绘图、Midjourney绘图。用户可以在界面上与聊天机器人进行对话,聊天机器人会根据用户的输入自动生成回复。同时也支持画图&a…...

如何在iPhone设备中查看崩溃日志
目录 如何在iPhone设备中查看崩溃日志 摘要 引言 导致iPhone设备崩溃的主要原因是什么? 使用克魔助手查看iPhone设备中的崩溃日志 奔溃日志分析 总结 摘要 本文介绍了如何在iPhone设备中查看崩溃日志,以便调查崩溃的原因。我们将展示三种不同的…...

对接第三方接口鉴权(Spring Boot+Aop+注解实现Api接口签名验证)
前言 一个web系统,从接口的使用范围也可以分为对内和对外两种,对内的接口主要限于一些我们内部系统的调用,多是通过内网进行调用,往往不用考虑太复杂的鉴权操作。但是,对于对外的接口,我们就不得不重视这个…...

微服务-理论(CAP,一致性协议)
CAP理论 关于CAP理论的介绍可以直接看这篇文章 CAP分别是什么? 一致性(Consistency 一致性包括强一致性,弱一致性,最终一致性。 一致性其实是指数据的一致性,为什么数据会不一致呢? 如上面这张图&…...

CTFshow web入门web128-php特性31
开启环境: 一个新的姿势,当php扩展目录下有php_gettext.dll时: _()是一个函数。 _()gettext() 是gettext()的拓展函数,开启text扩展get_defined_vars — 返回由所有已定义变量所组成的数组。 call_user_func — 把第一个参数作为回调函数调…...

再见2023,你好2024(附新年烟花python实现)
亲爱的朋友们: 写点什么呢,我已经停更两个月了。2023年快结束了,时间真的过得好快,总要写点什么留下纪念吧。这一年伴随着许多挑战和机会,给了我无数的成长和体验。坦白说,有时候我觉得自己好像是在时间的…...
Redis 的常用命令
一、Redis 通用命令 TYPE key:返回 key 所储存的值的类型。 OBJECT ENCODING key:返回key所储存的值的底层编码方式。 DEL key:该命令用于在 key 存在时删除 key。 EXPIRE key seconds:设置指定key的过期时间。 RENAME key newke…...

【模拟电路】模拟集成电路之神-NE555
一、集成电路NE555简介 二、功能框图与引脚说明 三、比较器(运放) 四、反相门(非门) 五、或非门 六、双稳态触发器 七、NE555的工作原理 集成电路NE555的芯片手册 C5157696 一、集成电路NE555简介 NE555起源于上个世纪70年代&a…...
收集最新的 Sci-Hub 网址(本文章持续更新2024)
自用收集最新的 Sci-Hub 网址 本文章持续更新收集 Sci-Hub 的可用网址链接仅供交流学习使用,如对您有所帮助,请收藏并推荐给需要的朋友,由于网站限制,不一定所有网址都能在您所在的位置访问,通常情况下,一…...
【Linux】C语言执行shell指令
在C语言中执行Shell指令 在C语言中,有几种方法可以执行Shell指令: 1. 使用system()函数 这是最简单的方法,包含在stdlib.h头文件中: #include <stdlib.h>int main() {system("ls -l"); // 执行ls -l命令retu…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
C++中string流知识详解和示例
一、概览与类体系 C 提供三种基于内存字符串的流,定义在 <sstream> 中: std::istringstream:输入流,从已有字符串中读取并解析。std::ostringstream:输出流,向内部缓冲区写入内容,最终取…...

JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
AGain DB和倍数增益的关系
我在设置一款索尼CMOS芯片时,Again增益0db变化为6DB,画面的变化只有2倍DN的增益,比如10变为20。 这与dB和线性增益的关系以及传感器处理流程有关。以下是具体原因分析: 1. dB与线性增益的换算关系 6dB对应的理论线性增益应为&…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...