【算法】 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;	}

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

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

相关文章

Illegal hex characters in escape (%) pattern

java.lang.NullPointerException 原因是关键字&#xff1a;5%葡萄糖注射液 其中的百分号通过HttpServletRequest的getParameter传到后端提示空指针异常&#xff0c;然后使用url格式&#xff0c;百分号的十六进制是%25&#xff08;百分号加25&#xff09; 在js代码中加入一段正…

Mybatis实现增删改查的两种方式-配置文件/注解

环境准备 1.数据库表tb_brand -- 删除tb_brand表 drop table if exists tb_brand; -- 创建tb_brand表 create table tb_brand(-- id 主键id int primary key auto_increment,-- 品牌名称brand_name varchar(20),-- 企业名称company_name varchar(20),-- 排序字段ordered int…

【SpringCloud Alibaba笔记】(2)Sentinel实现熔断与限流

Sentinel 概述 官网&#xff1a;https://github.com/alibaba/Sentinel 中文文档&#xff1a;https://sentinelguard.io/zh-cn/docs/introduction.html 类似Hystrix&#xff0c;以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热…

spdlog源码学习

前言 spdlog是一个跨平台c 的开源日志库 &#xff0c;可以head only 使用&#xff0c;包含部分modern c 语法&#xff0c; 更是兼容了c20 format&#xff0c;支持异步和格式化输出&#xff0c;通俗易懂&#xff0c;适合阅读。 源码下载 here 用法 直接贴上了 example.cpp …

四种方式实现[选择性注入SpringBoot接口的多实现类]

最近在项目中遇到两种情况&#xff0c;准备写个博客记录一下。 情况说明&#xff1a;Service层一个接口是否可以存在多个具体实现&#xff0c;此时应该如何调用Service&#xff08;的具体实现&#xff09;&#xff1f; 其实之前的项目中也遇到过这种情况&#xff0c;只不过我采…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux系统编程第二天-Linux开发板外设开发(物联技术666)

更多配套资料CSDN地址:点赞+关注,功德无量。更多配套资料,欢迎私信。 物联技术666_嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记-CSDN博客物联技术666擅长嵌入式C语言开发,嵌入式硬件,嵌入式培训笔记,等方面的知识,物联技术666关注机器学习,arm开发,物联网,嵌入式硬件,单片机…

操作系统课程设计——文件管理系统(C语言版)

操作系统系列文章 http://t.csdnimg.cn/7XAnU 文章目录 实验一、进程的创建与撤销&#xff1a;http://t.csdnimg.cn/po4V0 实验二、银行家算法&#xff1a;http://t.csdnimg.cn/O5zoF 目录 操作系统系列文章 文章目录 文件管理 一、目的 二、设计内容 三、 设计要求 …

Excel·VBA按指定顺序排序函数

与之前写过的《ExcelVBA数组冒泡排序函数》不同&#xff0c;不是按照数值大小的升序/降序对数组进行排序&#xff0c;而是按照指定数组的顺序&#xff0c;对另一个数组进行排序 以下代码调用了《ExcelVBA数组冒泡排序函数》bubble_sort_arr函数&#xff08;如需使用代码需复制…

如何在群晖7.2中运行WPS Office镜像容器并使用固定地址公网访问

文章目录 1. 拉取WPS Office镜像2. 运行WPS Office镜像容器3. 本地访问WPS Office4. 群晖安装Cpolar5. 配置WPS Office远程地址6. 远程访问WPS Office小结 7. 固定公网地址 wps-office是一个在Linux服务器上部署WPS Office的镜像。它基于WPS Office的Linux版本&#xff0c;通过…

LaTeX矩阵

在 LaTeX 中输入矩阵以及矩阵中增加公式。 LATEX 中 array 环境可以定义二维数组&#xff0c;具体需要定义列数&#xff0c;并用 \\ 换行&#xff0c;数组可作为一个公式块&#xff0c;在外套用 \left、\right 等定界符。 \mathbf{X} \left(\begin{array}{cccc}x_{11} &…

【AI】什么是大模型的偏见

目录 一、什么是大模型的偏见 二、偏见的危害 三、普通人可以做的一些偏见测试用例 1. 性别偏见测试&#xff1a; 2. 种族和民族偏见测试&#xff1a; 3. 职业偏见测试&#xff1a; 4. 年龄偏见测试&#xff1a; 5. 社会经济地位偏见测试&#xff1a; 6. 身体能力偏见…

Leetcode 3002. Maximum Size of a Set After Removals

Leetcode 3002. Maximum Size of a Set After Removals 1. 解题思路2. 代码实现3. 算法优化 题目链接&#xff1a;10037. Maximum Size of a Set After Removals 1. 解题思路 这一题的话我的思路就是分别以两个数组作为主数组&#xff0c;然后从中选择 n / 2 n/2 n/2个元素&…

接口限流方案

1.1 为什么要进行限流&#xff1f; 1.瞬时流量过高&#xff0c;服务被压垮&#xff1f; 2.恶意用户高频光顾&#xff0c;导致服务器宕机&#xff1f; 3.消息消费过快&#xff0c;导致数据库压力过大&#xff0c;性能下降甚至崩溃&#xff1f; 1.2 什么是限流 限流是对某一…

Zuul相关问题及到案(2024)

1、什么是Zuul&#xff1f;它在微服务架构中有什么作用&#xff1f; Zuul是Netflix开源的一种提供API网关服务的应用程序&#xff0c;它在微服务架构中扮演着流量的前门角色。主要功能包括以下几点&#xff1a; 路由转发&#xff1a;Zuul网关将外部请求转发到具体的微服务实例…

【Python常用函数】一文让你彻底掌握Python中的numpy.append函数

大数据时代的到来,使得很多工作都需要进行数据挖掘,从而发现更多有利的规律,或规避风险,或发现商业价值。而大数据分析的基础是学好编程语言。本文和你一起来探索Python中的append函数,让你以最短的时间明白这个函数的原理。也可以利用碎片化的时间巩固这个函数,让你在处…

高效管理文件方法:每4个文件前面加序号,4个文件后面又单独编号技巧

在日常工作中&#xff0c;文件管理是一项常见的任务。要更高效地管理文件&#xff0c;可以通过在每个文件前面加序号&#xff0c;并在每个序号对应的文件后面进行单独编号的方法来实现。这种方法有助于快速找到所需文件&#xff0c;也能提高工作效率。下面一起来看下云炫文件管…

2024出海潮,生态伙伴搭上华为HMS的“便车”?

作者 | 曾响铃 文 | 响铃说 回顾2023年&#xff0c;中国新能源车市场在加速内卷的同时&#xff0c;还诞生了一个 “超级物种”&#xff0c;那就是华为将车BU分拆。未来&#xff0c;华为智能汽车解决方案未来不仅会独立运营&#xff0c;还吸纳了庞大的盟友阵营&#xff0c;包括…

linux后台运行进程分类查看操作命令

例如需要查看所有运行的python程序进程&#xff1a; 执行的命令如下&#xff1a; ps -ef | grep python 解释&#xff1a; 在 UNIX 或类 UNIX 系统&#xff08;如 Linux&#xff09;中的作用是查找所有正在运行的与 Python 相关的进程。这个命令结合了两个常用的命令行工具…

R语言【base】——tempfile():返回一个字符串向量,这些字符串可以用作临时文件的名称

Package base version 4.2.0 Parameters tempfile(pattern "file", tmpdir tempdir(), fileext "") tempdir(check FALSE) 参数【pattern】&#xff1a;一个非空字符向量&#xff0c;给出名称的初始部分。 参数【tmpdir】&#xff1a;提供目录名称的…

修复HTTP动词篡改导致的认证旁路问题的方法

本文于2016年4月完成&#xff0c;发布在个人博客网站上。 诡异的问题 分析AppScan扫描报告的时候&#xff0c;发现报告里提示“HTTP动词篡改导致的认证旁路”&#xff0c;一个名字很长&#xff0c;很怪异的问题。咨询度娘没有获取到必要的信息&#xff0c;于是只好按照AppScan…