欢迎大家阅读本文章

如果大家对LCMGCD不是很熟悉,这篇文章将对你有帮助!

本文章也会把动态规划做一定的介绍

题目:

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详细介绍)干货满满~的更多相关文章

  1. 蓝桥杯Java真题解析

    上个月参加蓝桥杯省赛拿了个省一,自从比赛完之后就一直没怎么写代码了,还有一个多月就要国赛了,从现在开始准备下国赛,但是我也不想学什么算法,而且我还在准备考研,所以就打算只做下历年的真题,争取国赛拿个国 ...

  2. 第三届蓝桥杯预赛真题_第一题_两种微生物 X 和 Y

    /* 假设有两种微生物 X 和 Y X出生后每隔3分钟分裂一次(数目加倍),Y出生后每隔2分钟分裂一次(数目加倍). 一个新出生的X,半分钟之后吃掉1个Y,并且,从此开始,每隔1分钟吃1个Y. 现在已 ...

  3. Java实现 蓝桥杯 历届真题 稍大的串

    串可以按照字典序进行比较.例如: abcd 小于 abdc 如果给定一个串,打乱组成它的字母,重新排列,可以得到许多不同的串,在这些不同的串中,有一个串刚好给定的串稍微大一些.科学地说:它是大于已知串 ...

  4. 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 ...

  5. Java实现蓝桥杯历届真题国王的遗产

    国王的遗产 题目描述 X国是个小国.国王K有6个儿子.在临终前,K国王立下遗嘱:国王的一批牛作为遗产要分给他的6个儿子. 其中,大儿子分1/4,二儿子1/5,三儿子1/6,- 直到小儿子分1/9. 牛 ...

  6. 2018年第九届蓝桥杯B组题C++汇总解析-fishers

    2018年第九届蓝桥杯B组题C++解析-fishers 题型 第一题:第几天 第二题:明码 第三题:乘积尾零 第四题:测试次数 第五题:快速排序 第六题:递增三元组 第七题:螺旋折线 第八题:日志统计 ...

  7. 啤酒和饮料|2014年蓝桥杯B组题解析第一题-fishers

    啤酒和饮料|2014年第五届蓝桥杯B组题解析第一题-fishers 啤酒和饮料 啤酒每罐2.3元,饮料每罐1.9元.小明买了若干啤酒和饮料,一共花了82.3元. 我们还知道他买的啤酒比饮料的数量少,请 ...

  8. C语言蓝桥杯比赛原题和解析

    蓝桥杯:在计算机编程领域,是具有一定含金量的竞赛,用于选拔信息技术人才. 一般分为多个领域,其中包含了C/C#/C++/Java/Python等编程语言的测试题,多为算法的设计题. 下面,在搜题过程中 ...

  9. 黄金连分数|2013年蓝桥杯B组题解析第四题-fishers

    黄金连分数 黄金分割数0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些精密工程,常数的精度很重要.也许你听说过哈勃太空望远镜,它首次 ...

  10. 奇怪的分式|2014年蓝桥杯B组题解析第六题-fishers

    奇怪的分式 上小学的时候,小明经常自己发明新算法.一次,老师出的题目是: 1/4 乘以 8/5 小明居然把分子拼接在一起,分母拼接在一起,答案是:18/45 (参见图1.png) 老师刚想批评他,转念 ...

随机推荐

  1. resnet模型下载

    resnet模型下载: model_urls = { 'resnet18': 'https://s3.amazonaws.com/pytorch/models/resnet18-5c106cde.pt ...

  2. JS刷题自制参考知识

    (建议复制到本地,需要看的时候打开Typora,大纲点击要查的内容即可,我一般记不清某个方法的时候就查一下.) 基础 Typescript TypeScript是一个开源的.渐进式包含类型的JavaS ...

  3. 汇编程序 - TD调试

    为了写这个Blog,无奈的我深夜打开虚拟机,希望也能帮助一些人,因为好像真的有人不会欸!(→_→) 写在前面的话: 1. TD面板下的调试十分重要.可以观察内存(GOTO DS:XXXX)存放的位置与 ...

  4. 让 rtb 不显示 横纵 滚动条的方法

    让 rtb 不显示 横纵 滚动条的方法: a.设置属性: tb.ScrollBars=None; b.设置属性:rtb.WordWarp=False; c. 添加事件代码: rtb.ContentsR ...

  5. 【其他】etcd

    配置 node1 name: etcd-1 data-dir: /data/etcd/node1 listen-client-urls: http://127.0.0.1:6701 advertise ...

  6. PC端,知乎在不想登录的情况下一打开就弹出登录框的无痛解决办法

    基于chrome浏览器 第一步: chrome://settings/content/javascript 第二步:添加禁用项 [*.]zhihu.com

  7. docker学习随笔

    总结自https://zhuanlan.zhihu.com/p/187505981 Linux内核提供了Namespace技术来隔离PID/IPC/网络资源等,还提供了Control Group(cg ...

  8. svn操作方法

    1.SVN1.1.SVN概述1.1.1.为什么需要使用svn版本控制软件协作开发远程开发版本回退 1.1.2.解决之道SCM:软件配置管理所谓的软件配置管理实际就是对软件源代码进行控制与管理. CVS ...

  9. java 中文繁简体转换工具 opencc4j 使用介绍 1.8.0

    Opencc4j Opencc4j 支持中文繁简体转换,考虑到词组级别. 在线体验 Features 特点 严格区分「一简对多繁」和「一简对多异」. 完全兼容异体字,可以实现动态替换. 严格审校一简对 ...

  10. 第六章 C控制语句:分支和跳转

    6.1if语句 程序 #define _CRT_SECURE_NO_WARNINGS 1 //coladays.c -- 求出温度低于零度的天数 #include<stdio.h> int ...