【蓝桥杯】每日练习 Day19,20
目录
前言
蒙德里安的梦想
分析
最短Hamilton路径
分析
代码
乌龟棋
分析
代码
松散子序列
分析
代码
代码
前言
今天不讲数论(因为上课学数论真是太难了,只学了高斯消元)所以今天就不单独拿出来讲高斯消元了。今天讲一下昨天和今天做的四种题型(两个状压dp,两个线性dp),时间仓促,我们马上开始吧。
蒙德里安的梦想

分析
首先来分析一下暴力的时间复杂度,因为只有两种图形,所以我们只需要考虑一种图形的放法,随后在将另一种放进去即可,所以我们分析时间复杂度也只分析一种图形的放法,我们将两个相邻的方块看成一个整体,显然时间复杂度为:
考虑极限情况N = M = 11,结果是2^55左右,显然是超时的。所以暴力搜索不考虑。
我们注意到N和M都很小(这种一般就可以考虑能否使用状态压缩dp了,经验之谈),所以我们考虑状态压缩dp,用二进制枚举所有的选法。
因为我也不太能想出来这道题的解题思路是怎么来的,所以我这边就直接用答案套题目了。
我们枚举每一列的所有选法,状态总数就是
1 << n
我们设
m = 1 << n。
状态表示:dp[m][n] 枚举第n列使用m排列的所有选法。
状态转移:dp[m][n] += dp[s][n - 1],当然这两个状态必须是能够同时存在并且合法的。
现在我们来分析一下什么样的状态算是合法的,因为我们枚举的是横着摆放的所有方法,所以就必须满足放完之后能够使用竖着摆放的方块填满整个矩形,显然要想满足这个条件这一列连续不放置的方块数量就必须是偶数(我们是用每一列来划分的,所以默认前面的所有列都是已经放满的,无需考虑复杂情况。)
随后我们再来思考一下怎样算是这一层与上一层的状态是共存的,显然不能重复放置。所以我们的划分就已经完成了。
时间复杂度分析:大概是1亿左右,可以通过。
/*数位dp,因为只有两种方块并且必须填满才算合法情况,所以我们只枚举一种的放法随后判断这种方法是否合法。第一列所有状态都是合法的。
*/
#include<iostream>
#include<cstring>
using namespace std;
typedef long long LL;
const int N = 15, M = 1 << N;
int n, m;
LL dp[M][N]; //第N列以M的摆放方式放置的所有方案
bool is_realy[M];
//LL l;
int main()
{while(scanf("%d%d", &n, &m) && n && m){//memset(is_realy, false, sizeof is_realy);for(int i = 0; i < 1 << n; i++) //枚举所有状态{int cnt = 0; //记录非0长度is_realy[i] = true;for(int j = 0; j < n; j++) //查看每一位{if((i >> j) & 1) //是1{if(cnt & 1) //奇数{is_realy[i] = false; //非法状态break;}cnt = 0;}elsecnt++;}if(cnt & 1) is_realy[i] = false;}memset(dp, 0, sizeof dp); //初始化for(int i = 0; i < 1 << n; i++) if(is_realy[i])dp[i][1] = 1;for(int i = 2; i <= m; i++) //枚举每一层 0, m - 1是合法层{for(int j = 0; j < 1 << n; j++) //枚举当前状态for(int k = 0; k < 1 << n; k++) //枚举上一层状态if((j & k) == 0 && is_realy[j | k])dp[j][i] += dp[k][i - 1];}printf("%lld\n", dp[0][m]);}
}
最短Hamilton路径

分析
哈密尔顿路问题,每个结点都要经过一次且仅一次。
看到这个最终状态其实就能够感觉出来是动态规划了,话不多说,我们来考虑状态压缩dp。
状态表示:dp[i][i],表示以i结尾的包含i的路径的所有选法。
老规矩,分析上一个结点,所以我们枚举上一个结点。
状态转移:
dp[i][j] = min(dp[i][j], dp[i - 1 << j][k] + map[k][j])
时间复杂度分析:枚举路径数是2^n = 1e6,枚举每个结点和上一层结点是n * n,所以最终的时间复杂度就是,大概是
4亿左右,这道题时间限制是5s可以通过。
代码
// Hamilton路径——经过所有点一次且仅一次的路径
// dp[M][N] 从1出发,以n结尾的所有路径的最短值。
#include<iostream>
#include<cstring>
using namespace std;
const int N = 21, M = 1 << N;
int n;
int map[N][N];
int dp[M][N];
int main()
{scanf("%d", &n);for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)scanf("%d", map[i] + j);// 枚举所有路径memset(dp, 0x3f, sizeof dp);dp[1][0] = 0;for(int i = 0; i < 1 << n; i++) //枚举所有路径{for(int j = 0; j < n; j++) //枚举以哪个点结尾{if(i >> j & 1) // 路径中包含i,枚举上一个点结尾for(int k = 0; k < n; k++){if(i >> k & 1) //也在路径中dp[i][j] = min(dp[i][j], dp[i - (1 << j)][k] + map[k][j]);}}}printf("%d", dp[(1 << n) - 1][n - 1]);
}
乌龟棋

分析
本来以为是背包但是发现结果与选的个数无关只与顺序有关并且是一定可以选完的,所以排除掉背包。
发现题目中强调了只有四种跳跃幅度,所以从这里入手,如何来表示状态呢?
欸?有一种“非常暴力”的表示方法——dp[N][M][M][M][M],显然这个状态数量有点多了,大概是350 * 41 * 41 * 41 * 41 = 8.9亿,严重超时,超空间。
随后我们来分析一下能不能优化呢?可以发现N和每一个M彼此之间都是有关联的,只需要知道其余4个就可以求出第5个,所以我们可以将状态优化到4维,因为N最大,所以我们优先考虑优化掉N,状态就变为了:dp[M][M][M][M],大概数41 * 41 * 41 * 41 = 2560000空间上大概是9M,可以通过。
状态表示有了接下来我们就来思考一下状态计算。
显然
dp[a][b][c][d] = max(dp[a - 1][b][c][d], dp[a][b - 1][c][d], dp[a][b][c - 1][d], dp[a][b][c][d - 1]) + s。
代码
/*01背包? 对于每个位置,枚举使用哪张卡片到达? 会出现重复吧。。。学到了新的思路,每个卡片都存储一下选择了多少张,这样就不会出现重复的了还能保证没有先后顺序的随机查找
*/
#include<iostream>
using namespace std;
const int N = 360, M = 42;
int n, m;
int a[N], s[5];
int dp[M][M][M][M]; //四维状态存储每种卡片的使用情况
int main()
{scanf("%d%d", &n, &m);for(int i = 1; i <= n; i++)scanf("%d", &a[i]);for(int i = 1; i <= m; i++){int x; scanf("%d", &x);s[x]++; }//dp[0][0][0][0] = a[1];for(int A = 0; A <= s[1]; A++)for(int B = 0; B <= s[2]; B++)for(int C = 0; C <= s[3]; C++)for(int D = 0; D <= s[4]; D++){if(A) dp[A][B][C][D] = max(dp[A][B][C][D], dp[A - 1][B][C][D]); if(B) dp[A][B][C][D] = max(dp[A][B][C][D], dp[A][B - 1][C][D]); if(C) dp[A][B][C][D] = max(dp[A][B][C][D], dp[A][B][C - 1][D]); if(D) dp[A][B][C][D] = max(dp[A][B][C][D], dp[A][B][C][D - 1]); dp[A][B][C][D] += a[1 + A + 2 * B + 3 * C + 4 * D];}printf("%d", dp[s[1]][s[2]][s[3]][s[4]]);return 0;
}
松散子序列

分析
题目要求就是找出acsii相加并且每个字符在原串中的距离要大于1的所有子序列的最大值(语文题)。
这道题很简单,主播给大家提供两种思路。
第一种,以子序列的最后一个结点划分,运用最长上升子序列的思想,然每次更新最大值即可。(这也是我认为最简单的思路)。
状态表示:dp[i]表示以第i个字符结尾的子序列的最大值。
状态转移:dp[i] = max(dp[i - 2], dp[i - 3], ...) + str[i],因为我们求的是线性值,所以可以使用贪心优化,每次只拿最大值判断即可。
代码
#include<iostream>
using namespace std;
const int N = 1000010;
int mxx;
int dp[N];
int n;
char str[N];
int main()
{scanf("%s", str + 1);for(int i = 1; str[i]; n = i++){dp[i] = mxx + str[i] - 'a' + 1; //记录最大值mxx = max(mxx, dp[i - 1]);}printf("%d", max(dp[n], dp[n - 1]));return 0;
}
第二种呢,是使用状态机dp,显然每个字符只有两种状态——选或不选,随后运用背包的思想表示出状态即可。
状态表示:
dp[i][2]表示第i个字符选或不选。
状态转移:
dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]),dp[i][1] = dp[i - 1][0] + s[i]。
代码
#include<iostream>
using namespace std;
const int N = 1000010;
int dp[N][2];
int n;
char str[N];
int main()
{scanf("%s", str + 1);for(int i = 1; str[i]; n = i++){dp[i][0] = max(dp[i - 1][0], dp[i - 1][1]);dp[i][1] = dp[i - 1][0] + str[i] - 'a' + 1;}printf("%d", max(dp[n][0], dp[n][1]));return 0;
}
对于这个状态呢,我们可以将其优化到一维——dp[i]存储选或不选的最大值(类似背包)。
状态表示:
dp[i] = max(dp[i - 1], dp[i - 2]) + str[i],前面是不选的最值,后面是选的最值。
#include<iostream>
using namespace std;
const int N = 1000010;
int dp[N];
int n;
char str[N];
int main()
{scanf("%s", str + 1);for(int i = 1; str[i]; n = i++)dp[i] = max(dp[i - 1], dp[i - 2] + str[i] - 'a' + 1);printf("%d", dp[n]);return 0;
}
相关文章:
【蓝桥杯】每日练习 Day19,20
目录 前言 蒙德里安的梦想 分析 最短Hamilton路径 分析 代码 乌龟棋 分析 代码 松散子序列 分析 代码 代码 前言 今天不讲数论(因为上课学数论真是太难了,只学了高斯消元)所以今天就不单独拿出来讲高斯消元了。今天讲一下昨天和…...
《AI大模型应知应会100篇》第7篇:Prompt Engineering基础:如何与大模型有效沟通
第7篇:Prompt Engineering基础:如何与大模型有效沟通 摘要 Prompt Engineering(提示工程)是与大模型高效沟通的关键技能。通过精心设计的Prompt,可以让模型生成更准确、更有用的结果。本文将从基础知识到高级策略&…...
微服务架构技术栈选型避坑指南:10大核心要素深度拆解
微服务架构的技术栈选型直接影响系统的稳定性、扩展性和可维护性。以下从10大核心要素出发,结合主流技术方案对比、兼容性评估、失败案例及优化策略,提供系统性选型指南。 1. 服务框架与通信 关键考量点 扩展性:框架需支持定制化扩展&#x…...
Elasticsearch 正排索引
一、正排索引基础概念 在 Elasticsearch 中,正排索引用于存储完整的文档内容,以便通过文档ID 快速定位文档的字段值。正排索引通过 Doc Values 和 Store Fields 两种形式,为聚合、排序、脚本计算等场景提供高效支持。Doc Values 的列式存储设…...
Spring实现WebScoket
SpringWeb编程方式分为Servlet模式和响应式。Servlet模式参考官方文档:Web on Servlet Stack :: Spring Framework,响应式(Reacive)参考官方文档:Web on Reactive Stack :: Spring Framework。 WebSocket也有两种编程方…...
Token是什么?
李升伟 整理 “Token” 是一个多义词,具体含义取决于上下文。以下是几种常见的解释: 1. 计算机科学中的 Token 定义:在编程和计算机科学中,Token 是源代码经过词法分析后生成的最小单位,通常用于编译器和解释器。 …...
odoo-045 ModuleNotFoundError: No module named ‘_sqlite3‘
文章目录 一、问题二、解决思路 一、问题 就是项目启动,本来好好地,忽然有一天报错,不知道什么原因。 背景: 我是在虚拟环境中使用的python3.7。 二、解决思路 虚拟环境和公共环境直接安装 sqlite3 都会报找不到这个库的问题…...
cesium加载CTB生成的地形数据
由于CTB生成的地形数据是压缩的(gzip)格式,需要在nginx加上特殊配置才可以正常加载,NGINX全部配置如下 worker_processes 1; events {worker_connections 1024; } http {include mime.types;default_type application/o…...
前端JS高阶技法:序列化、反序列化与多态融合实战
✨ 摘要 序列化与反序列化作为数据转换的核心能力,与多态这一灵活代码设计的核心理念,在现代前端开发中协同运作,提供了高效的数据通信与扩展性支持。 本文从理论到实践,系统解析: 序列化与反序列化的实现方式、使用…...
TS中的Class
基本用法 implements implements 关键字用于传递对类产生约束的数据类型 interface AnimalInfo{name:stringrace:stringage:number }interface AnimalCls{info:AnimalInfosayName():void} class Animal implements AnimalCls{info:AnimalInfoconstructor(info:AnimalInfo) {t…...
RustDesk 开源远程桌面软件 (支持多端) + 中继服务器伺服器搭建 ( docker版本 ) 安装教程
在需要控制和被控制的电脑上安装软件 github开源仓库地址 https://github.com/rustdesk/rustdesk/releases 蓝奏云盘备份 ( exe ) https://geek7.lanzouw.com/iPf592sadqrc 密码:4esi 中继服务器设置 使用docker安装 sudo docker image pull rustdesk/rustdesk-server sudo…...
【计网速通】计算机网络核心知识点与高频考点——数据链路层(二)
数据链路层核心知识点(二) 涵盖局域网、广域网、介质访问控制(MAC层)及数据链路层设备 上文链接:https://blog.csdn.net/weixin_73492487/article/details/146571476 一、局域网(LAN,Loacl Area Network&am…...
STM32单片机入门学习——第3-4节: [2-1、2]软件安装和新建工程
写这个文章是用来学习的,记录一下我的学习过程。希望我能一直坚持下去,我只是一个小白,只是想好好学习,我知道这会很难,但我还是想去做! 本文写于:2025.04.01 STM32开发板学习——第一节: [1-1]课程简介 前言开发板说明引用解答和…...
W3C XML Schema 活动
W3C XML Schema 活动 概述 W3C XML Schema(XML Schema)是万维网联盟(W3C)定义的一种数据描述语言,用于定义XML文档的结构和约束。XML Schema为XML文档提供了一种结构化的方式,确保数据的一致性和有效性。本文将详细介绍W3C XML Schema的活动,包括其发展历程、主要特点…...
爬虫【Scrapy-redis分布式爬虫】
Scrapy-redis分布式爬虫 1.Scrapy-redis实现增量爬虫 增量爬虫的含义 就是前面所说的的暂停、恢复爬取 安装 # 使用scrapy-redis之前最好将scrapy版本保持在2.8.0版本, 因为2.11.0版本有兼容性问题 pip install scrapy==2.8.0 pip install scrapy-redis -i https://pypi.tun…...
intellij Idea 和 dataGrip下载和安装教程
亲测有效 第一步:卸载老版本idea/Datagrip (没有安装过的可跳过此步骤) 第二步:下载idea/dataGrip安装包 建议选择2022以后的版本 官网: https://www.jetbrains.com/datagrip/download/other.html 选择dataGrip 的…...
轻量级搜索接口技术解析:快速实现关键词检索的Java/Python实践
Hi,你好! 轻量级搜索接口技术解析:快速实现关键词检索的Java/Python实践 接口特性与适用场景 本接口适用于需要快速集成搜索能力的开发场景,支持通过关键词获取结构化搜索结果。典型应用场景包括: 垂直领域信息检索…...
架构设计基础系列:事件溯源模式浅析
图片来源网络,侵权删 1. 引言 1.1 研究背景 传统CRUD模型的局限性:状态覆盖导致审计困难、无法追溯历史。分布式系统复杂性的提升:微服务架构下数据一致性、回滚与调试的需求激增。监管合规性要求:金融、医疗等领域对数…...
ResNet系列和ViT系列预训练模型权重文件下载
一、简单介绍 OpenAI CLIP项目提供的预训练模型权重文件列表,主要包含两种架构系列和不同规模配置: ResNet系列 (RN) 基础版本:RN50(ResNet-50)扩展版本:RN50x4、RN50x16、RN50x64(宽度扩展&am…...
【力扣hot100题】(035)二叉树的中序遍历
正常方法递归很简单,于是又学了一种栈的方法。 原理如下:每次循环先尽量将目前节点入栈并左移,没有左节点时回到栈首节点将目前节点放入结果容器中并移出栈外,目前节点变为该节点的右节点,循环结束条件是目前节点为nu…...
《数字图像处理》教材寻找合作者
Rafael Gonzalez和Richard Woods所著的《数字图像处理》关于滤波器的部分几乎全错,完全从零开始写,困难重重。关于他的问题已经描述在《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》。 现寻找能够共同讨论、切磋、…...
批量删除 txt/html/json/xml/csv 等文本文件中的重复行
在文本文件中,可能会存在一些重复的数据行,这可能不是我们期望的,因此我们会碰到需要删除文本文件中重复行的情况。如果是人工删除,当文件较大或者数量较多的时候,处理的难度会较大。今天就给大家介绍一下批量删除文本…...
LangChain 使用向量数据库介绍与使用
LangChain 是一个用于构建大语言模型(LLM)应用的框架,而向量数据库在 LangChain 中主要用于实现检索增强生成(RAG, Retrieval-Augmented Generation),即通过向量搜索从外部知识库中快速检索相关信息,辅助大模型生成更准确的回答。以下是具体的使用方法: 1. 核心流程 L…...
基于微信小程序的智慧乡村旅游服务平台【附源码】
基于微信小程序的智慧乡村旅游服务平台(源码L文说明文档) 目录 4系统设计 4.1系统功能设计 4.2系统结构 4.3.数据库设计 4.3.1数据库实体 4.3.2数据库设计表 5系统详细实现 5.1 管理员模块的实现 5.1.1旅游景点管理…...
d202542
一、142.环形链表I 142. 环形链表 II - 力扣(LeetCode) 用set统计一下 如果再次出现那么就环的第一个return返回就行 public ListNode detectCycle(ListNode head) {Set<ListNode> set new HashSet<>();ListNode cur head;while(cur ! …...
NodeTextFileCollectorScrapeError 报警原因及解决方法
现象 prometheus 经常有告警 NodeTextFileCollectorScrapeError 查看 node-exporter 日志出现如下报错 time2025-04-01T06:43:18.266Z levelERROR sourcetextfile.go:248 msg"failed to collect textfile data" collectortextfile fileipmitool.prom err"fail…...
RapidJSON 处理 JSON(高性能 C++ 库)(四)
第四部分:RapidJSON 处理 JSON(高性能 C++ 库) 📢 快速掌握 JSON!文章 + 视频双管齐下 🚀 如果你觉得阅读文章太慢,或者更喜欢 边看边学 的方式,不妨直接观看我录制的 RapidJSON 课程视频!🎬 视频里会用更直观的方式讲解 RapidJSON 的核心概念、实战技巧,并配有…...
80. Linux内核定时器实验
一、Linux内核定时器原理 1.1、内核时间管理 1、Cortex-M内核使用systick作为系统定时器。 2、硬件定时器、软件定时器,原理是依靠系统定时器来驱动。 3、linux内核频率可以配置,图形化界面配置。 4、重点,HZ表示系统节拍率, 1.…...
Java 可变参数全解析:动态参数传递的实践指南
Java 可变参数全解析:动态参数传递的实践指南 一、可变参数:Java 方法的灵活扩展 在狂神说 Java 第 49 集课程中,我们系统学习了 Java 可变参数的核心原理。作为 Java SE 5 引入的重要特性,可变参数允许方法接受动态数量的输入&…...
C++类与对象(上):从入门到实践
目录 一、引言 二、面向过程和面向对象初步认识 2.1 面向过程编程 2.2 面向对象编程 三、类的引入 四、类的定义 4.1 定义格式 4.2 定义方式 4.3 成员变量命名规则建议 五、类的访问限定符及封装 5.1 访问限定符 5.2 封装 六、类的作用域 七、类的实例化 7.1 概念…...
