当青训营遇上码上掘金之寻友之旅

66 阅读2分钟

当青训营遇上码上掘金之寻友之旅,本篇文章为 「青训营 X 码上掘金」主题创作活动入营版 中主题三寻友之旅的创作灵感和过程,主要采用动态规划的思想进行计算,使用go语言进行编写。

题目

小青要找小码去玩,他们的家在一条直线上,当前小青在地点 N ,小码在地点 K (0≤N , K≤100 000),并且小码在自己家原地不动等待小青。小青有两种交通方式可选:步行和公交。
步行:小青可以在一分钟内从任意节点 X 移动到节点 X-1 或 X+1
公交:小青可以在一分钟内从任意节点 X 移动到节点 2×X (公交不可以向后走) 请帮助小青通知小码,求小青最快到达时间是多久?
输入: 两个整数 N 和 K
输出: 小青到小码家所需的最短时间(以分钟为单位)

思路

本文采用动态规划的思想,采用贪心策略进行推导,用dp一维数组记录值,dp[x]表示从N到x的最短时间:

  1. 首先考虑小青在小码的右边的特殊情况(即K<N),因为公交乘不能向后走所以只能步行。在遍历循环的时候,对于x<N的情况,最短时间就是N−x,直接可以计算dp数组i从0到N-1。
  2. 对于i>N开始,N−>i的最短路径可以考虑以下情况:
    • 从左边步行走一步过来,即接着在i-1时候继续步行:dp[i]=dp[i1]+1dp[i]=dp[i-1]+1
    • 从上一站坐车过来,即i为偶数:dp[i]=dp[i/2]+1dp[i]=dp[i/2]+1
    • 从右边往回走一步,即i为奇数,考虑在i-1处坐车再走一步 dp[(i1)/2]+1dp[(i-1)/2]+1和先走一步再在i+1处坐车 dp[(i+1)/2]+1dp[(i+1)/2]+1
  3. 最后当i超过K之后还需要考虑超出再回退是否时间会更短:dp[i]+iKdp[i]+i-K

具体公式如下:

0=<i<N——dp[i] = dp[i+1]+1; 步行回退 
i>N————dp[i] = min(步行到i,总公交到i)+1 
= min(dp[i-1], dp[i/2])+1; (i-1>=0i/2为偶数)
= min(dp[i-1], dp[(i-1)/2]+1, dp[(i+1)/2]+1)+1;(i-1>=0i/2为奇数)

完整代码链接:code.juejin.cn/pen/7195098…