2021年蓝桥杯python真题-路径(数论+动态规划)(LCM、GCD和DP详细介绍)干货满满~
欢迎大家阅读本文章
如果大家对LCM和GCD不是很熟悉,这篇文章将对你有帮助!
本文章也会把动态规划做一定的介绍
题目:

GCD和LCM的讲解:
GCD的实现-辗转相除法:
在数学中,辗转相除法,又称欧几里得算法(Euclidean algorithm),是求取最大公约数的一种算法。辗转相除法首次出现于欧几里得的《几何原本》中的第Ⅶ卷,书中的命题ⅰ和命题ⅱ所描述的就是辗转相除法,而在中国,辗转相除法最早出现在《九章算法》中。
希腊数学家是这样处理的,在我们预先构造的矩形中,我们先以矩形的短边构造正方形,然后再去计算这样的正方形可以在大矩形中「最多」放置多少个,这个计算过程可以用取余的方式进行计算。接下来,我们再用长边余下的长度构建正方形,在去试图铺满剩下未被覆盖的部分,然后计算这个正方形最多可以放置几个,直到我们找到这样一个正方形,这个正方形可以完全铺满整个大矩形。那么这个正方形就是我们最终要找的答案,自然而然的,这个正方形的边长也就是我们要找的两数的最大公约数。

LCM的实现:
算法分解定理: 任何一个大于1的自然数 N,如果N不为质数,那么N可以唯一分解成有限个质数的乘积 N=P1a1 P2a2P3a3…Pnan,这里P1<P2<P3…<Pn均为质数,其中指数ai是正整数。这样的分解称为 N 的标准分解式。

所以可以推导出:gcd(a, b) * lcm(a, b) = a * b
代码实现:
def gcd(a, b):
if b == 0: return a
return gcd(b, a % b)
def lcm(a, b):
return a * b // gcd(a, b)
️注意:python里的math库有gcd(),可以直接调用,但是蓝桥杯的系统没有lcm()方法!新版的python有lcm()方法,为了保险起见,在做题的时候,lcm()需要手写一遍。
动态规划讲解:
DP是一种容易理解的计算思想。有一些问题有两个特征:重叠子问题、最优子结构。用DP可以高效率的处理具有这两特征的问题。
重叠子问题:
子问题是大问题的小版本,它们的计算步骤完全一样。计算大问题的时候,需要重复计算小问题。这就是重叠子问题。
最优子结构:
最优子结构的意思是,大问题的最优解;可以通过小问题的最优解推导出大问题的最优解。
DP的过程一般需要:状态设计、状态转移方程、DP代码实现、滚动数组。
题目解答:
我拿到题目的时候,有点蒙,不知道题目想要求什么。后来经过反复的读题,我恍然大悟!
题目大意是:从1结点走到2021结点的最短路径,因为结点到结点的距离是不一样,所以有很多走法,我们的目的就是找到路径最短的一条。题目中还有限制条件,就是结点差不能大于21,也就是每次从n个结点最远走到n+21结点。然后题目规定了,结点到结点之间到距离是两个结点的最小公倍数。
看来出题人很有心思啊!如果不会求最大公约数(GCD)和最小公倍数(LCM),又不会用动态规划(DP),三者少一者,这题都做不出来!
from math import * # gcd()是math库里的方法
def lcm(i, j): # 手写lcm()
return (i * j) // gcd(i, j)
首先写个lcm(),方便后续求两个结点的路径。
INF = 1<<100 # 模拟无穷大
dp = [INF] * 2022
构建线性dp,用来存放走到 i 结点时最短的路径dp[i]
# 特殊值处理
for i in range(1, 23):
dp[i] = i
对于特殊的结点 i,我们直接赋值给它。为什么特殊呢?因为结点1到结点22,它们的最短路径都是它们本身。也是为了写后面的代码少个判断,能偷个懒。
# dp找最短路径
for i in range(23, 2022):
for j in range(i-21, i):
tmp = dp[j] + lcm(i, j)
if tmp < dp[i]: dp[i] = tmp
这里我们可以看到第二层for循环 j 是从i - 21开始的,所以第一层for循环 i 是从23开始,前面的1到22我单独写了层循环赋值。 假设 i == 25 的时候,我们的目的就是要求出1到25结点之间到最短距离,倒数第二个结点到最后一个结点最多差21,举个例子:结点3不能直接到结点25,因为它们的结点差大于21,所以可以是从4结点到25结点,从5结点到25结点……24结点到25结点。
第二个for循 j 的目的就是找倒数第二个结点到最后一个结点 i 的最短路径,每次求出的路径用tmp变量记录,如果tmp比dp[i]小的话,dp[i] = tmp。
如果还不能理解的话看下面的模拟:
题目:找出结点1到结点25之间到最短路径(限制条件和上面说的一样)
分析:dp[1]~dp[22]的值都是它们的索引(1和任意数 a 的最小公倍数都是a)
dp[23] = dp[2] + lcm(2, 23) = 48 这是dp[23]最小的情况
dp[24] = dp[4] + lcm(4, 24) = 28 这是dp[24]最小的情况
dp[25] = dp[5] + lcm(5, 25) = 30 这是dp[25]最小的情况
如果之后数据量大的时候,后面的dp[x]可以直接调用前面的dp[y]。
这也是一种最优子结构。
完整代码:
from math import *
def lcm(i, j):
return (i * j) // gcd(i, j)
INF = 1<<100
dp = [INF] * 2022
# 特殊值处理
for i in range(1, 23):
dp[i] = i
# dp找最短路径
for i in range(23, 2022):
for j in range(i-21, i):
tmp = dp[j] + lcm(i, j)
if tmp < dp[i]: dp[i] = tmp
print(dp[2021])
完结撒花祝每个奋斗的人都能成功!

2021年蓝桥杯python真题-路径(数论+动态规划)(LCM、GCD和DP详细介绍)干货满满~的更多相关文章
- 蓝桥杯Java真题解析
上个月参加蓝桥杯省赛拿了个省一,自从比赛完之后就一直没怎么写代码了,还有一个多月就要国赛了,从现在开始准备下国赛,但是我也不想学什么算法,而且我还在准备考研,所以就打算只做下历年的真题,争取国赛拿个国 ...
- 第三届蓝桥杯预赛真题_第一题_两种微生物 X 和 Y
/* 假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍). 一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y. 现在已 ...
- Java实现 蓝桥杯 历届真题 稍大的串
串可以按照字典序进行比较.例如: abcd 小于 abdc 如果给定一个串,打乱组成它的字母,重新排列,可以得到许多不同的串,在这些不同的串中,有一个串刚好给定的串稍微大一些.科学地说:它是大于已知串 ...
- Java实现 蓝桥杯 历届真题 数字拆分
正整数可以表示为若干正整数的累加和. 如,对于正整数n=6,可以分划为: 5+1 4+2 4+1+1 3+3 3+2+1 3+1+1+1 2+2+2 2+2+1+1 2+1+1+1+1 1+1+1+1 ...
- Java实现蓝桥杯历届真题国王的遗产
国王的遗产 题目描述 X国是个小国.国王K有6个儿子.在临终前,K国王立下遗嘱:国王的一批牛作为遗产要分给他的6个儿子. 其中,大儿子分1/4,二儿子1/5,三儿子1/6,- 直到小儿子分1/9. 牛 ...
- 2018年第九届蓝桥杯B组题C++汇总解析-fishers
2018年第九届蓝桥杯B组题C++解析-fishers 题型 第一题:第几天 第二题:明码 第三题:乘积尾零 第四题:测试次数 第五题:快速排序 第六题:递增三元组 第七题:螺旋折线 第八题:日志统计 ...
- 啤酒和饮料|2014年蓝桥杯B组题解析第一题-fishers
啤酒和饮料|2014年第五届蓝桥杯B组题解析第一题-fishers 啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道他买的啤酒比饮料的数量少,请 ...
- C语言蓝桥杯比赛原题和解析
蓝桥杯:在计算机编程领域,是具有一定含金量的竞赛,用于选拔信息技术人才. 一般分为多个领域,其中包含了C/C#/C++/Java/Python等编程语言的测试题,多为算法的设计题. 下面,在搜题过程中 ...
- 黄金连分数|2013年蓝桥杯B组题解析第四题-fishers
黄金连分数 黄金分割数0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些精密工程,常数的精度很重要.也许你听说过哈勃太空望远镜,它首次 ...
- 奇怪的分式|2014年蓝桥杯B组题解析第六题-fishers
奇怪的分式 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) 老师刚想批评他,转念 ...
随机推荐
- 关于php pconnect长连接如何刷新连接的讨论
由于每个pconnect所建立的连接信息和单个进程绑定.线上偶发了redis在某一台机器php-fpm上连接正常而无法进行任何操作的问题. 先说结论 查看redis拓展官方文档 close方法 有一句 ...
- 07.异常、多线程、Lambda 表达式
一.异常 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. 异常体系 根类 java.lang.Throwable 两个直接子类 java.lang.Error 严重错误Er ...
- test.sh 监听进程是否存在
监听myloader进程是否结束,结束后把时间输出到 /root/time.log vim test.sh #!/bin/bash #确保PRO查询进程唯一 PRO="myloader&qu ...
- Surge 开启脚本功能后,京东自动签到总结
本人小白,花费半天时间才弄好,写下这个给自己和后来人指路. Surge 开启脚本功能后,京东自动签到获取京豆总结: 1.注意 去 Raw 真实地址下载 js https://github.com/No ...
- 【Leetcode】 剑指offer:字符串(简单)--Day03
剑指 Offer 05. 替换空格 请实现一个函数,把字符串 s 中的每个空格替换成"%20". 逐字符遍历原字符串,遍历过程中对存放结果的字符串分情况更新. class Solu ...
- iframe.contentWindows使用
一.在使用iframe的页面,要操作这个iframe里面的DOM元素可以用: contentWindow.contentDocument(测试的时候chrome浏览器,要在服务器环境下) 1.先获取i ...
- mac git远程仓库错误解决方法
mac更新后不知道怎么回事,git时出现了 Permission denied (publickey). 经查询后得出原因 1.首先给git进行config的配置 git config --globa ...
- 【LeetCode回溯算法#06】复原IP地址详解(练习如何处理边界条件,判断IP合法性)
复原IP地址 力扣题目链接(opens new window) 给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式. 有效的 IP 地址 正好由四个整数(每个整数位于 0 到 255 ...
- Echarts中slider滑块调整样式
今天遇到了一个问题,记录一下. 效果图. 原型图 一个页面中,引入了echarts的柱状图来动态显示数据,由于柱状图太高,echarts没有自动生成的滚动条,所以就用slider滑块手写了一个,但是效 ...
- while与do-while的区别是什么,怎么用?
前言 在上一篇文章中,壹哥给大家讲解了循环的概念,并重点给大家讲解了for循环的使用.但在Java中,除了for循环之外,还有while.do-while.foreach等循环形式.今天壹哥就再用一篇 ...
