试题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