当前位置: 首页 > news >正文

【题目解析】蓝桥杯23国赛C++中高级组 - 斗鱼养殖场

【题目解析】蓝桥杯23国赛C++中高级组 - 斗鱼养殖场

题目链接跳转:点击跳转

前置知识:

  1. 了解过基本的动态规划。
  2. 熟练掌握二进制的位运算。

题解思路

这是一道典型的状压动态规划问题。设 d p i , j dp_{i, j} dpi,j 表示遍历到第 i i i 行的时候,当前行以 j ( b a s e 2 ) j_{(base2)} j(base2) 的形式排列乌龟可以构成的方案数。

对于每一行的方案,我们可以用一个二进制来表示。例如二进制数字 10100 10100 10100,表示有一个横向长度为 5 5 5 的场地中,第 1 , 3 1, 3 1,3 号位置分别放置了一只小乌龟。因此,每一种摆放状态都可以用一个二进制数字来表示。我们也可以通过遍历的方式来遍历出二进制的每一种摆放状态。

首先,我们预处理出横排所有放置乌龟的合法情况。根据题意,两个乌龟不能相邻放置,因此在二进制中,不能有两个 1 1 1 相邻。如何预处理出这种情况呢?我们可以使用位运算的方法:

如果存在一个二进制数字有两个 1 1 1 相邻,那么如果我们对这个数字 x x x 进行位运算操作 (x << 1) & x 的结果或 (x >> 1) & x 的结果必定大于等于 1 1 1。我们通过把这种情况排除在外。同时,我们还需要注意有些格子中不能放置乌龟。这一步也可以通过二进制的方法预处理掉,如果网箱在第 i i i 一个格子中不能放置乌龟,那么在枚举所有方案数的时候直接忽略掉第 i i i 位为 1 1 1 的情况即可。

接下来如何保证上下两行的乌龟不冲突?假如上一行的摆放状态是 y y y,当前行的摆放状态为 j j j,如果 i & j 的结果大于等于 1 1 1,也可以证明有两个数字 1 1 1 在同一位置上。因此我们也需要把这种情况排除在外。

综上所述,我们可以得出状态转移方程: d p i , j = d p i , j + d p i − 1 , k dp_{i, j} = dp_{i, j} + dp_{i-1, k} dpi,j=dpi,j+dpi1,k。其中, j j j k k k 表示所有横排合法的方案。答案就是 A N S = ∑ j = 0 2 M − 1 d p N , j \mathtt{ANS} = \sum_{j=0}^{2^M-1}{dp_{N, j}} ANS=j=02M1dpN,j

状态的初始化也很简单,另 d p 0 , 0 = 1 dp_{0, 0} = 1 dp0,0=1​,表示一只乌龟都不放有一种摆放方案。

时间复杂度

通过观察上述代码,在枚举所有状态和转移状态的时候有三层循环,分别是枚举当前行、枚举当前行的合法摆放情况以及枚举上一行的摆放情况。因此总时间复杂度约为 O ( n × 2 M × 2 M ) = O ( n × 2 M 2 ) = O ( n × 4 M ) O(n \times 2^M \times 2^M) = O(n \times 2^{M^2}) = O(n \times 4^M) O(n×2M×2M)=O(n×2M2)=O(n×4M)。但由于合法的摆放数量远远少于 2 M 2^M 2M,因此实际情况下程序运行的速度会快许多。

代码实现

本题的代码实现如下。在输出的时候需要减一,因为不放置也是一种合法情况,根据题目要求需要把这一合法情况排除。

#include <iostream>
using namespace std;const int MOD = 1e9+7;
int n, m, ans;
int arr[505][505];
// 所有横排合法的情况。
int terrain[505];
int ok[1050], cnt;
int dp[505][1050];int main(){cin >> n >> m;for (int i=1; i<=n; i++){for (int j=1; j<=m; j++){cin >> arr[i][j];}}// 预处理非法地形。for (int i=1; i<=n; i++){for (int j=1; j<=m; j++){terrain[i] = (terrain[i] << 1) + !arr[i][j];}}// 预处理出所有横排的合法情况。for (int i=0; i<(1<<m); i++){if (((i<<1)|(i>>1)) & i) continue;ok[++cnt] = i;}dp[0][1] = 1;// 枚举。for (int i=1; i<=n; i++){for (int s1=1; s1<=cnt; s1++){  // 枚举当前行。if (ok[s1] & terrain[i]) continue;for (int s2=1; s2<=cnt; s2++){  // 枚举上一行。if (ok[s2] & terrain[i-1]) continue;if (ok[s1] & ok[s2]) continue;dp[i][s1] = (dp[i][s1] + dp[i-1][s2]) % MOD;}}}// 统计答案。int ans = 0;for (int i=1; i<=cnt; i++)ans = (ans + dp[n][i]) % MOD;cout << ans - 1 << endl;return 0;
}

本题的 Python 代码如下,Python 可以通过本题的所有测试点:

MOD = int(1e9 + 7)
n, m, ans = 0, 0, 0
arr = [[0] * 505 for _ in range(505)]
terrain = [0] * 505
ok = [0] * 1050
dp = [[0] * 1050 for _ in range(505)]
cnt = 0def main():global n, m, cnt, ans# 输入 n 和 mn, m = map(int, input().split())# 输入 arr 数组for i in range(1, n + 1):arr[i][1:m + 1] = map(int, input().split())# 预处理非法地形for i in range(1, n + 1):for j in range(1, m + 1):terrain[i] = (terrain[i] << 1) + (1 - arr[i][j])# 预处理出所有横排的合法情况for i in range(1 << m):if ((i << 1) | (i >> 1)) & i:continuecnt += 1ok[cnt] = idp[0][1] = 1# 枚举for i in range(1, n + 1):for s1 in range(1, cnt + 1):  # 枚举当前行if ok[s1] & terrain[i]:continuefor s2 in range(1, cnt + 1):  # 枚举上一行if ok[s2] & terrain[i - 1]:continueif ok[s1] & ok[s2]:continuedp[i][s1] = (dp[i][s1] + dp[i - 1][s2]) % MOD# 统计答案ans = 0for i in range(1, cnt + 1):ans = (ans + dp[n][i]) % MODprint(ans - 1)if __name__ == "__main__":main()

再提供一个暴力解法用于对拍:

#include <iostream>
using namespace std;const int MOD = 1e9+7;
int n, m, ans;
int arr[505][505];
int dx[] = {0, 1, -1, 0};
int dy[] = {1, 0, 0, -1};// 深度优先搜索 Brute Force
void dfs(int x, int y){if (x > n) {ans += 1;ans %= MOD;return ;}if (y > m){dfs(x+1, 1);return ;}if (arr[x][y] == 0){dfs(x, y+1);return ;}// 不放鱼dfs(x, y+1);// 放鱼for (int i=0; i<4; i++){int cx = x + dx[i];int cy = y + dy[i];if (cx < 1 || cy < 1 || cx > n || cy > m) continue;if (arr[cx][cy] == 2) return ;}arr[x][y] = 2;dfs(x, y+1);arr[x][y] = 1;return ;
}int main(){cin >> n >> m;for (int i=1; i<=n; i++){for (int j=1; j<=m; j++){cin >> arr[i][j];}}// dfs 暴力dfs(1, 1);cout << ans-1 << endl;return 0;
}

相关文章:

【题目解析】蓝桥杯23国赛C++中高级组 - 斗鱼养殖场

【题目解析】蓝桥杯23国赛C中高级组 - 斗鱼养殖场 题目链接跳转&#xff1a;点击跳转 前置知识&#xff1a; 了解过基本的动态规划。熟练掌握二进制的位运算。 题解思路 这是一道典型的状压动态规划问题。设 d p i , j dp_{i, j} dpi,j​ 表示遍历到第 i i i 行的时候&a…...

JavaScript可视化:探索顶尖的图表库

JavaScript可视化&#xff1a;探索顶尖的图表库 在这个被数据驱动的时代&#xff0c;你有没有想过&#xff0c;数据本身是如何变得有意义的&#xff1f;答案就是数据可视化。通过图表和图形&#xff0c;我们不仅可以看到数据&#xff0c;还可以感受到它&#xff0c;从而做出明…...

谷歌AI大模型Gemini API快速入门及LangChain调用视频教程

1. 谷歌Gemini API KEY获取及AI Studio使用 要使用谷歌Gemini API&#xff0c;首先需要获取API密钥。以下是获取API密钥的步骤&#xff1a; 访问Google AI Studio&#xff1a; 打开浏览器&#xff0c;访问Google AI Studio。使用Google账号登录&#xff0c;若没有账号&#xf…...

进入容器:掌控Docker的世界

进入容器:掌控Docker的世界 在这个快速发展的技术时代,你是否曾被Docker的庞大生态所吸引?那么,有没有想过在这个容器化的世界里,如何快速高效地“进入”这些隐藏在虚拟墙后的容器呢?容器就如同魔法箱,装载着应用与服务,而你,通过探索这些容器,能够更好地管理、排除…...

初始Linux(二)基础命令

前言&#xff1a; 之前那一篇我们已经介绍了一部分的基础命令&#xff0c;当然那只不过是九牛一毛&#xff0c;本篇我们继续介绍一些比较重要且需要掌握的基础命令。 mv命令&#xff1a; 其实这个命令有两个功能&#xff0c;一个是移动&#xff08;剪切&#xff09;文件&#…...

STM32 OLED

文章目录 前言一、OLED是什么&#xff1f;二、使用步骤1.复制 OLED.C .H文件1.1 遇到问题 2.统一风格3.主函数引用头文件3.1 oled.h 提供了什么函数 4.介绍显示一个字符的函数5. 显示十进制函数的讲解 三、使用注意事项3.1 配置符合自己的引脚3.2 花屏总结 前言 提示&#xff…...

伦敦金实时行情决策辅助!

在伦敦金实时交易的过程中&#xff0c;投资者主要依赖技术分析来辅助自己的投资决策。与基本面分析不同&#xff0c;技术分析侧重于研究金价的走势和市场行为&#xff0c;通过图表和技术指标来预测未来的市场走势。常用的技术分析方法包括&#xff1a; 趋势线和支撑阻力位&…...

​Leetcode 746. 使用最小花费爬楼梯​ 入门dp C++实现

问题&#xff1a;Leetcode 746. 使用最小花费爬楼梯 给你一个整数数组 cost &#xff0c;其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用&#xff0c;即可选择向上爬一个或者两个台阶。 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 请你…...

路由协议常见知识点

路由协议是网络通信的基础&#xff0c;主要负责在网络中传递数据包&#xff0c;并确保它们从源节点传递到目标节点。本文将介绍一些常见的路由协议知识点&#xff0c;包括路由协议的分类、特性、配置与管理以及常见问题。 一、路由协议的分类 距离矢量路由协议&#xff1a; R…...

多模态大语言模型(MLLM)-InstructBlip深度解读

前言 InstructBlip可以理解为Blip2的升级版&#xff0c;重点加强了图文对话的能力。 模型结构和Blip2没差别&#xff0c;主要在数据集收集、数据集配比、指令微调等方面下文章。 创新点 数据集收集&#xff1a; 将26个公开数据集转换为指令微调格式&#xff0c;并将它们归类…...

网页前端开发之Javascript入门篇(7/9):字符串

Javascript字符串 什么是字符串&#xff1f; 答&#xff1a;其概念跟 Python教程 介绍的一样&#xff0c;只是语法上有所变化。 在 Javascript 中&#xff0c;一个字符串变量可以看做是其内置类String的一个实例&#xff08;Javascript会自动包装&#xff09;。 因此它拥有一…...

双登股份再战IPO:数据打架,实控人杨善基千万元股权激励儿子

撰稿|行星 来源|贝多财经 近日&#xff0c;双登集团股份有限公司&#xff08;下称“双登股份”&#xff09;递交招股书&#xff0c;准备在港交所主板上市&#xff0c;中金公司、建银国际、华泰国际为其联席保荐人。 贝多财经了解到&#xff0c;这并非双登股份首次向资本市场…...

4.Python 函数(函数的定义、函数的传入参数、函数的返回值、None 类型、函数说明文档、变量的作用域)

一、函数快速入门 1、函数概述 函数是组织好的&#xff0c;可重复使用的&#xff0c;用来实现特定功能的代码段 name "Hello World" name_length len(name)print(f"{name} 的长度为 {name_length}") # Hello World 的长度为 11len() 是Python 内置的函…...

【JavaEE】——文件IO

阿华代码&#xff0c;不是逆风&#xff0c;就是我疯 你们的点赞收藏是我前进最大的动力&#xff01;&#xff01; 希望本文内容能够帮助到你&#xff01;&#xff01; 目录 一&#xff1a;认识文件 1&#xff1a;文件的概念 2&#xff1a;文件的结构 3&#xff1a;文件路径…...

Python的pandas库基本操作(数据分析)

一、安装&#xff0c;导入 1、安装 使用包管理器安装&#xff1a; pip3 install pandas 2、导入 import pandas as pd as是为了方便引用起的别名 二、DateFrame 在Pandas库中&#xff0c;DataFrame 是一种非常重要的数据结构&#xff0c;它提供了一种灵活的方式来存储和…...

软件测试(平铺版本)

目录 黑盒测试&#xff1a; 定义: 示例&#xff1a;登录功能的黑盒测试 适合使用黑盒测试的情况 几种常见的黑盒测试方法&#xff1a; 1. 等价类划分&#xff08;Equivalence Partitioning&#xff09; 2. 边界值分析&#xff08;Boundary Value Analysis&#xff09; …...

树控件QTreeWidget

树控件跟表格控件类似&#xff0c;也可以有多列&#xff0c;也可以只有1列&#xff0c;可以有多行&#xff0c;只不过每一行都是一个QTreeWidgetItem&#xff0c;每一行都是一个可以展开的树 常用属性和方法 显示和隐藏标题栏 树控件只有水平标题栏 //获取和设置标题栏的显…...

Python酷库之旅-第三方库Pandas(139)

目录 一、用法精讲 626、pandas.plotting.scatter_matrix方法 626-1、语法 626-2、参数 626-3、功能 626-4、返回值 626-5、说明 626-6、用法 626-6-1、数据准备 626-6-2、代码示例 626-6-3、结果输出 627、pandas.plotting.table方法 627-1、语法 627-2、参数 …...

昇思学习打卡营学习记录:CycleGAN壁画修复

按照提示&#xff0c;运行实训代码 进入实训平台&#xff1a;https://xihe.mindspore.cn/projects 选择“jupyter 在线编辑器” 启动“Ascend开发环境” &#xff1a;Ascend开发环境需要申请&#xff0c;大家可以申请试试看 启动开发环境后&#xff0c;在左边的文件夹中&am…...

南京大学《软件分析》李越, 谭添——1. 导论

导论 主要概念: soundcompletePL领域概述 动手学习 本节无 文章目录 导论1. PL(Programming Language) 程序设计语言1.1 程序设计语言的三大研究方向1.2 与静态分析相关方向的介绍与对比静态程序分析动态软件测试形式化(formal)语义验证(verification) 2. 静态分析:2.1莱斯…...

CVPR 2025新秀OverLoCK上手实测:在COCO数据集上跑目标检测,比MogaNet-B高1% AP是怎么做到的?

OverLoCK实战指南&#xff1a;如何在COCO目标检测任务中超越MogaNet-B 1% AP 计算机视觉领域的主干网络架构正在经历一场静默革命。2025年CVPR最新收录的OverLoCK网络以其创新的"先概览再聚焦"设计理念&#xff0c;在多个视觉任务中展现出惊人的性能突破。本文将带您…...

高效获取B站视频:downkyi开源工具全方位使用指南

高效获取B站视频&#xff1a;downkyi开源工具全方位使用指南 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#xff09…...

Java微服务在Istio中出现“偶发503 no healthy upstream”?7分钟定位Sidecar健康检查盲区与Liveness Probe冲突真相

第一章&#xff1a;Java微服务在Istio中偶发503问题的现象与影响在基于Istio构建的服务网格环境中&#xff0c;Java微服务&#xff08;尤其是采用Spring Cloud Kubernetes或原生Spring Boot Istio Sidecar部署模式&#xff09;频繁出现偶发性HTTP 503 Service Unavailable响应…...

服务器很卡,是CC攻击造成的吗

之前有客户反馈&#xff0c;服务器有一段时间使用总是会遇到卡的情况&#xff0c;查看并无流量攻击的情况&#xff0c;程序也未进行过什么修改&#xff0c;用户人数也没有什么变化。来咨询是什么原因导致的。导致机器卡的情况&#xff0c;一般有带宽不够&#xff0c;硬件性能不…...

AutoHotkey脚本编译指南:3步将.ahk文件转为独立可执行程序

AutoHotkey脚本编译指南&#xff1a;3步将.ahk文件转为独立可执行程序 【免费下载链接】Ahk2Exe Official AutoHotkey script compiler - written itself in AutoHotkey 项目地址: https://gitcode.com/gh_mirrors/ah/Ahk2Exe 你是否曾想过将精心编写的AutoHotkey自动化…...

Qwen2.5-14B-Instruct在AI编剧赛道的突破:像素剧本圣殿Glitch标题交互体验分享

Qwen2.5-14B-Instruct在AI编剧赛道的突破&#xff1a;像素剧本圣殿Glitch标题交互体验分享 1. 像素剧本圣殿&#xff1a;AI编剧的新范式 在数字内容创作领域&#xff0c;剧本创作一直是最具挑战性的任务之一。传统编剧需要花费大量时间构思情节、塑造角色、打磨对白&#xff…...

Spring Boot 3.0 + Java 17 微服务实战:用Gradle统一管理多模块依赖与版本,告别配置混乱

Spring Boot 3.0 Java 17 微服务实战&#xff1a;用Gradle统一管理多模块依赖与版本 在微服务架构中&#xff0c;依赖管理往往成为开发者的噩梦。想象一下&#xff0c;当你需要在十几个子模块中同步更新Spring Boot版本时&#xff0c;传统的做法是在每个模块的构建文件中逐一修…...

用ESP32和TB6612FNG做个遥控小车:从硬件接线到Arduino代码调试全记录

从零打造ESP32智能遥控小车&#xff1a;硬件选型、代码优化与避坑指南 项目背景与核心组件解析 去年夏天&#xff0c;我在工作室里堆满了各种电机和开发板&#xff0c;试图为侄子制作一个生日礼物——能通过手机控制的遥控小车。经过多次迭代&#xff0c;最终选择了ESP32TB6612…...

5分钟零代码部署:Live2D AI虚拟助手让你的网站活起来

5分钟零代码部署&#xff1a;Live2D AI虚拟助手让你的网站活起来 【免费下载链接】live2d_ai 基于live2d.js实现的动画小人ai&#xff0c;拥有聊天功能&#xff0c;还有图片识别功能&#xff0c;可以嵌入到网页里 项目地址: https://gitcode.com/gh_mirrors/li/live2d_ai …...

AzurLaneAutoScript:碧蓝航线全自动游戏助手,释放您的双手与时间

AzurLaneAutoScript&#xff1a;碧蓝航线全自动游戏助手&#xff0c;释放您的双手与时间 【免费下载链接】AzurLaneAutoScript Azur Lane bot (CN/EN/JP/TW) 碧蓝航线脚本 | 无缝委托科研&#xff0c;全自动大世界 项目地址: https://gitcode.com/gh_mirrors/az/AzurLaneAuto…...