2021年第十二届蓝桥杯软件类省赛python组“回路计算“问题

news2024/11/27 12:38:08

说明

这一题我不会做,看了官方给出的标准答案之后才明白,我把我学到的思路写下来。

题目

蓝桥学院由21栋教学楼组成,教学楼编号1到21。对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。

小蓝现在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?两个访问方案不同是指存在某个i,小蓝在两个访问方法中访问完教学楼i后访问了不同的教学楼。

官方给出的标准答案代码

from math import gcd
n = int(input())
m = 1 << n
dp = [[0 for j in range(n)] for i in range(m)]
load = [[False for j in range(n)] for i in range(n)] 
for i in range(1, n + 1):
    for j in range(1, n + 1):
        if gcd(i, j) == 1:
            load[i - 1][j - 1] = True
dp[1][0] = 1
for i in range(1, m): 
    for j in range(n):
        if i >> j & 1: 
            for k in range(n): 
                if i - (1 << j) >> k & 1 and load[k][j]:  
                    dp[i][j] += dp[i - (1 << j)][k]
print(sum(dp[m - 1]) - dp[m - 1][0])

我的理解

状态压缩

参考链接:https://blog.csdn.net/weixin_45697774/article/details/104874248

状态压缩属于运筹学的动态规划问题。动态规划问题的求解方法大致分成两种,一种是对递归问题的记忆化求解,另一种是把大问题看作是多阶段的决策求解。本题使用多阶段决策求解。
状态压缩是用二进制或者三进制等来表示某种状态,然后把这些二进制或者三进制压缩成10进制,从而达到节约存储空间的目的。

解题思路

  1. 题目说如果两个楼的编号互为质数,那么这两个楼之间就有一条路。那么我们就先求出来哪些楼之间存在路。
    用一个二维数组load存储各个楼之间的互通关系,比如load[1][3]=True表示1号楼和3号楼编号互质,它们之间存在通路;load[2][4]=False表示2号楼和三号楼编号不互质,它们之间不存在通路。
  2. 对于状态压缩,必须需要定义一个二维数组dp(也有可能是三维数组,视具体情况而定,本题必须定义二维数组)用来存储在i结点时是state状态的所有可能的数量。
    dp[i][state]表示当前正在i结点,当前的系统状态是state时的所有可能的数量。比如dp[8][6]=24表示当前正在8号结点,当前已经走过的结点是3号和2号的所有可能的结果的数量是24。

对当前已经走过的结点是3号和2号的解释:state=6,6的二进制是0110,按照从右往左的顺序,编号从1开始,对应的编号是2和3的位置是1,表示已经走过了,为0表示还没有走过。如果所有的结点都走过了,那么state的二进制全部为1

  1. 因为dp[i][state]中的i表示当前所处的结点编号,state表示当前系统的状态。所以对于题目中的21个楼,i的值的范围是1~21.state的值的范围是000…01到111…11(21位二进制)。
  2. 状态压缩数组定义完成之后,我们需要把所有可能的情况都遍历一遍,把所有满足条件的情况相加就得到最终的结果,具体方法是:
    第一步,先用一个for循环遍历state的所有情况(000…11到111…11)
    第二步,找到一个state中二进制是1的一个结点
    第三步,再找到是state中第二个二进制是1的结点。第一个找到的1的结点编号作为当前正处在的结点,第二个找到的1的结点编号作为上一次到达的结点的编号。
    第四步,把上一次的所有可能结果和这次所有可能的结果相加。
    第五步,从第一部循环,直到所有的state遍历完毕。

我写的代码

"""
蓝桥学院由21栋教学楼组成,教学楼编号1到21。
对于两栋教学楼a和b,当a和b互质时,a和b之间有一条走廊直接相连,两个方向皆可通行,否则没有直接连接的走廊。

小蓝现在第一栋教学楼,他想要访问每栋教学楼正好一次,最终回到第一栋教学楼(即走一条哈密尔顿回路),请问他有多少种不同的访问方案?
两个访问方案不同是指存在某个i,小蓝在两个访问方法中访问完教学楼i后访问了不同的教学楼。"""
import math
import time

"""运算符优先级:括号>单目运算符>乘除>加减>移位运算符>比较运算符"""

n = int(input('输入教学楼的个数:'))
m = 1 << n  # m 是所有可能的状态(从000...00到1111...11)

startTime = time.time()

"""定义一个二维数组load,用来存储节点i和j是否互质的信息,比如load[i][j] = True 表示i和j互质,若load[i][j] = False 表示i和j不互质"""
load = [[False for i in range(n)] for j in range(n)]
for i in range(1,n+1):
    for j in range(1,n+1):
        if math.gcd(i, j) == 1:  # 如果i和j互质
            load[i-1][j-1] = True

"""定义状态压缩数组dp[i][state],i表示当前在结点i,当前的状态是state时的所有方案数目,比如dp[2][4]表示当前在2号结点,已经走过的结点是4(0..00100)的所有可能的方案数目"""
dp = [[0 for i in range(m)] for j in range(n+1)]  # n + 1 是因为一共有个结点并且让下标从1开始,m 是因为一共有m种状态,而state只是所有状态中的一种(
                                                    # 000..00-111..11中的一个,用m就可以遍历000..00-111..11中的任意一个)
dp[1][1] = 1  # 当前还没有走,起始结点是1,此时的状态state=1(0000..01)时所有可能的结果只有1种

for i in range(1, m):  # 遍历所有可能的状态,状态000..00认为不算,所以从1开始
    for j in range(n):  # 遍历每一个结点,j表示当前所处的结点编号
        if i >> j & 1:  # 如果i从右边往左边数第j位是1,表示当前在从右往左数第j位结点
            for k in range(n):  # 再一次遍历1到n的所有结点,看看哪一些结点已经被走过了(1),哪一些结点还没有被走过(0)
                if i - (1 << j) >> k & 1 and load[j][k]:  # i - (1<<j)表示把i的从右往左数第j位变成0,i -(1 << j) >> k & 1表示看看i -(1
                                                            # << j)的从右往左数第k位是不是1
                    dp[j+1][i] += dp[k+1][i - (1 << j)]  # dp[j][i]的数目就是从上一个结点到这一个结点的数目加上上一个结点之前的数目i - (1 << j)是上一个结点的状态
su = 0
for i in range(1, n+1):
    # print(dp[i][m-1])
    su += dp[i][m-1]  # m-1就是全1(111...11)的状态

endTime = time.time()
"""881012367360"""

print(su)
print('运行时间:', endTime - startTime)

运算结果

在这里插入图片描述

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

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

相关文章

CRM之线索管理的demo搭建方法

1、简介 1.1、案例简介 本文将介绍&#xff0c;如何搭建CRM-线索管理。 1.2、应用场景 CRM-线索管理应用完整记录所有线索资料&#xff0c;合理的对线索进行领取、分配、退回、跟进&#xff0c;实现线索管理智能化。 2、设置方法 2.1、表单搭建 1&#xff09;新建主表【新…

【日常系列】LeetCode《25·贪心2》

数据规模->时间复杂度 <10^4 &#x1f62e;(n^2) <10^7:o(nlogn) <10^8:o(n) 10^8<:o(logn),o(1) 内容 lc 976 &#xff1a;三角形的最大周长 https://leetcode.cn/problems/largest-perimeter-triangle/ 提示&#xff1a; 3 < nums.length < 10^4 1 &l…

Dubbo优雅启动(附源码分析)

Dubbo优雅启动 1. 启动有什么问题 我们知道&#xff0c;应用在运行了一段时间后&#xff0c;执行速度会比刚启动的时候要快。这是因为在 Java 里面&#xff0c;在运行过程中&#xff0c;JVM 虚拟机会把高频的代码编译成机器码&#xff0c;被加载过的类也会被缓存到 JVM 缓存中…

主数据和元数据、数据标准、数据质量有什么关系

企业数据治理涉及的工作很广&#xff0c;包括数据标准、数据质量、数据安全、数据共享机制、元数据管理、主数据管理等。主数据作为企业的黄金数据&#xff0c;对于企业信息化管理具有重要意义。本文将对主数据的概念及主数据与数据治理体系中的几个核心部分的关系和大家做一个…

oracle 查询到的结果在快捷地写入到excel过程中标题部分正确的处理方式

点击上方“Python爬虫与数据挖掘”&#xff0c;进行关注回复“书籍”即可获赠Python从入门到进阶共10本电子书今日鸡汤羌笛何须怨杨柳&#xff0c;春风不度玉门关。大家好&#xff0c;我是皮皮。一、前言前几天在Python最强王者交流群【粉丝】问了一个pandas数据处理的问题&…

一篇文章让你掌握HTML(上)

目录 前言 1. 基础认知 1.1 HTML概念 1.2 Web标准 2. HTML骨架结构 3. 开发工具的基本使用 4. 语法规范 4.1 HTML的注释 4.2 HTML标签的结构 4.3 HTML标签的关系 5. 排版标签 5.1 标题标签 5.2 段落标签 5.3 换行标签 5.4 水平线标签 6. 文本格式化标签…

清华教授极力推荐的三本入门学习Python书籍

目录 Python入门书&#xff08;适合初学者&#xff09; Python进阶书&#xff08;适合有基础的&#xff09; Python数据科学&#xff08;适合初学者&#xff09; Python入门书&#xff08;适合初学者&#xff09; 这应该是世界上最畅销的Python编程书&#xff0c;没有之一。…

实战|记一次2022某地HVV中的木马逆向分析

声明&#xff1a;本文仅限于技术讨论与分享&#xff0c;严禁用于非法途径。若读者因此作出任何危害网络安全行为后果自负&#xff0c;与本号及原作者无关。前言事情是这样的&#xff0c;国庆前期某地HVV&#xff0c;所以接到了客户通知他们收到了钓鱼邮件想要溯源直接下载文件逆…

电子模块|光照强度传感器模块 GY-302及其驱动(arduino、STC51、STM32)

电子模块|光照强度传感器模块 GY-302及其驱动&#xff08;arduino、STC51、STM32&#xff09;实物照片模块简介模块特点原理图驱动程序arduinoSTC51STM32实物照片 模块简介 BH1750是一种用于两线式串行总线接口的数字型光强度传感器集成电路。这种集成电路可以根据收集的光线强…

【Linux】文件操作、文件描述符和重定向

​&#x1f320; 作者&#xff1a;阿亮joy. &#x1f386;专栏&#xff1a;《学会Linux》 &#x1f387; 座右铭&#xff1a;每个优秀的人都有一段沉默的时光&#xff0c;那段时光是付出了很多努力却得不到结果的日子&#xff0c;我们把它叫做扎根 目录&#x1f449;重新谈论文…

【数据结构】5.1 树和二叉树的定义

前言 数形结构的关系是 1 对 n 的&#xff0c;树的每个元素后面都可以有多个后继&#xff0c;但是只能有 1 个前趋。 树形结构&#xff08;非线性结构&#xff09; 结点之间有分支具有层次关系 5.1.1 数的定义 树&#xff08;Tree&#xff09;是 n &#xff08;n > 0&…

java中javaSE与javaEE的区别

javaSE是什么&#xff1f; 怎么说吧&#xff0c;可以理解为javaSE是java的基石&#xff0c;如果将java程序想象成一座高楼大厦&#xff0c;那么javaSE就是地基。 官方的解释&#xff1a; Java SE&#xff08;Java Platform&#xff0c;Standard Edition&#xff09; Java SE 以…

实验室设计基本原则SICOLAB

实验室设计基本原则SICOLAB实验室设计、实验室建设施工SICOLAB实验室布局必须符合实验流程的规律&#xff0c;从样品接收、样品暂存、试剂和耗材储存、前处理和准备、样品分析测试、清洗到废物回收和处理&#xff0c;都必须有一个清晰的流程。要区分人流和物流&#xff0c;以及…

SQL DELETE 语句

DELETE 语句用于删除表中的记录。 SQL DELETE 语句 DELETE 语句用于删除表中的行。 SQL DELETE 语法 DELETE FROM table_name WHERE condition; 参数说明&#xff1a; table_name&#xff1a;要删除的表名称。condition&#xff1a;删除条件&#xff0c;用于指定哪些数据要…

小程序开发经验分享(4)-框架的选择

3个小程序开发框架 小程序开发公认的3个小程序开发框架: 原生、wepy、mpvue。3者个有利弊: 原生框架:微信的亲儿子,可直接在微信开发者工具中开发,方便调试,结构直接对应微信文档,框架无缝升级,最快支持最新版本的开发基础库。缺点是原生开发提供的开发方式比较朴素,…

2023年网络安全比赛--网络安全事件响应中职组(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1.黑客通过网络攻入本地服务器,通过特殊手段在系统中建立了多个异常进程,找出启动异常进程的脚本,并将其绝对路径作为Flag值提交; 2.黑客通过网络攻入本地服务器,通过特殊手段在系统…

2022年12月国产数据库大事记-墨天轮

本文为墨天轮技术社区整理的2022年12月国产数据库大事件和重要产品发布消息。 目录 12月国产数据库大事记&#xff08;时间线&#xff09;产品/版本发布兼容认证排行榜新增数据库厂商活动相关资料 12月国产数据库大事记&#xff08;时间线&#xff09; 12月2日&#xff0c;…

linux环境tomcat发布系统

目录 1、上传需要发布的war 包 2、查看当前java线程 3、杀死需要启动的服务的java线程 3、修改上传的war包名称&#xff0c;删除原来的代码包 4、重新启动程序 5、查看启动日志 1、上传需要发布的war 包 通过XFTP上传war 包到 服务器 tomcat -->webapps 目录下。 注…

测试开发 | 相比 Selenium,Web 自动化测试框架 Playwright 有哪些强大的优势?

Playwright 是由微软的研发团队所开发的一款 Web 自动化测试框架&#xff0c;这个框架具有多平台、跨语言的特点。除了基本的自动化测试能力之外&#xff0c;同时它还具备非常强大的录制功能、追踪功能。以下是 Playwright 与 Selenium 的对比。 由此可见&#xff0c;Playwrigh…

Nginx编译安装vts监控模块

目录 1、环境准备 2、编译安装Nginx源码 2.1、安装依赖 2.2、编译安装Nginx 2.3验证Nginx安装 3、Nginx添加配置 3.11、Http模块下面添加 3.1.2、添加status访问页面 4、启动Nginx 4.3、访问前端页面 1、环境准备 参考Github vts模块参考Github nginx-1.20.2.tar.…