2021年蓝桥python组省赛(三)

试题D:路径

动态规划问题,还涉及到一点的最短路径的思想,但主要还是利用动态规划来解决问题。思路如下:

1、定义数组元素的含义

最终是要得到1到2021之间的最短路径,显然1是无法直接到达2021,因为题目规定两节点的差的绝对值大于21就没有边,故我们要找到那个和1有边的且路径最短的结点,所以dp[i]就可以表示结点i到结点1的最短距离,即最终要求dp[2021]。再用dp[j]表示当前节点(与i能有边的结点)到i的最短路径。

2、找出数组元素间的关系式

dp[j] = min(dp[j],dp[i]+lcm(i,j)),dp[j]表示之前计算的,当前节点到i的最短路径(没有赋值前是无穷大),dp[i]+lcm(i,j)则表示dp[i]与能够有边的结点的最短路径。

3、找出初始条件

显然dp[1] = 1

另外,在计算lcm(i,j)时采用的思路是: 两数的最小公约数=两数相乘/两数最大公因数

代码如下:

#两数的最小公约数=两数相乘/两数最大公因数
def lcm(x,y):
    num = x*y
    while y:
        x,y = y,x%y
    return num/x
n = 2021
dp = [float('inf')]*(n+1)#float('inf')表示正无穷
dp[1] = 0#初始值,1到1的距离为0
for i in range(1,n+1):#遍历所有点
    for j in range(i+1,i+22):#与当前点能有边的点
        if j>n:
            break
        dp[j] = min(dp[j],dp[i]+lcm(i,j))
print(dp[n])

脑子还是有点糊,需要及时复习复习。动态规划的思想临时学的,这篇写的很不错,学习:http://t.csdn.cn/oyzjX 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值