当前位置: 首页 > 知识库问答 >
问题:

到达末端的最小跳跃次数动态编程MIG

谢阳曜
2023-03-14

给定一个数组,从第一个元素开始验证到达终点需要多少步。

示例:arr=[1,3,5,8,4,2,6,7,0,7,9]

1-

3个步骤。

到目前为止,我从极客那里得到了以下代码:

def jumpCount(x, n): 
  jumps = [0 for i in range(n)] 

  if (n == 0) or (x[0] == 0): 
      return float('inf') 

  jumps[0] = 0


  for i in range(1, n): 
      jumps[i] = float('inf')   
      for j in range(i): 
          if (i <= j + x[j]) and (jumps[j] != float('inf')): 
              jumps[i] = min(jumps[i], jumps[j] + 1) 
              break                 
  return jumps[n-1]     

def jumps(x):
  n = len(x)
  return jumpCount(x,n) 

x = [1, 3, 5, 8, 4, 2, 6, 7, 0, 7, 9]

print(jumps(x))

但是我想打印出哪些数字是最短的路径(1-3-8)。我如何调整代码来做到这一点?

我试图创建一个j的列表,但是由于5在循环中进行了测试,所以也添加了它。

问题的链接:https://www.geeksforgeeks.org/minimum-number-of-jumps-to-reach-end-of-a-given-array/

共有1个答案

葛子昂
2023-03-14

基本思想是,您需要一个辅助结构来帮助您跟踪最小路径。这些类型的结构通常被称为“backpointers”(在我们的例子中,你可以称它们为“forwardpointers”,因为我们正在前进,duh)。我的代码递归地解决了这个问题,但同样的问题也可以迭代地解决。策略如下:

jumps_vector = [ 1, 3, 5, 8, 4, 2, 6, 7, 0, 7, 9 ]

"""
fwdpointers holds the relative jump size to reach the minimum number of jumps
for every component of the original vector
"""
fwdpointers = {}

def jumps( start ):
    if start == len( jumps_vector ) - 1:
        # Reached the end
        return 0
    if start > len( jumps_vector ) - 1:
        # Cannot go through that path
        return math.inf
    if jumps_vector[ start ] == 0:
        # Cannot go through that path (infinite loop with itself)
        return math.inf

    # Get the minimum in a traditional way
    current_min = jumps( start + 1 )
    fwdpointers[ start ] = start + 1
    for i in range( 2, jumps_vector[ start ] + 1 ):
        aux_min = jumps( start + i )
        if current_min > aux_min:
            # Better path. Update minimum and fwdpointers
            current_min = aux_min
            # Store the (relative!) index of where I jump to
            fwdpointers[ start ] = i

    return 1 + current_min

在这种情况下,变量fwdpointers存储我跳转到的位置的相对索引。例如,fwdpointers[0]=1,因为我将跳转到相邻的数字,但是fwdpointers[1]=2,因为我将在下一次跳转时跳转两个数字。

完成此操作后,只需在main()函数上稍微进行后处理即可:

if __name__ == "__main__":
    min_jumps = jumps( 0 )
    print( min_jumps )

    # Holds the index of the jump given such that
    # the sequence of jumps are the minimum
    i = 0
    # Remember that the contents of fwdpointers[ i ] are the relative indexes
    # of the jump, not the absolute ones
    print( fwdpointers[ 0 ] )
    while i in fwdpointers and i + fwdpointers[ i ] < len( jumps_vector ):
        print( jumps_vector[ i + fwdpointers[ i ] ] )
        # Get the index of where I jump to
        i += fwdpointers[ i ]
        jumped_to = jumps_vector[ i ]

我希望这回答了你的问题。

编辑:我认为迭代版本更具可读性:

results = {}
backpointers = {}
def jumps_iter():
    results[ 0 ] = 0
    backpointers[ 0 ] = -1
    for i in range( len( jumps_vector ) ):
        for j in range( 1, jumps_vector[ i ] + 1 ):
            if ( i + j ) in results:
                results[ i + j ] = min( results[ i ] + 1, results[ i + j ] )
                if results[ i + j ] == results[ i ] + 1:
                    # Update where I come from
                    backpointers[ i + j ] = i
            elif i + j < len( jumps_vector ):
                results[ i + j ] = results[ i ] + 1
                # Set where I come from
                backpointers[ i + j ] = i

    return results[ len( jumps_vector ) - 1 ]

以及后处理:

i = len( jumps_vector ) - 1
print( jumps_vector[ len( jumps_vector ) - 1 ], end = " " )
while backpointers[ i ] >= 0:
    print( jumps_vector[ backpointers[ i ] ], end = " " )
    i = backpointers[ i ]
print()
 类似资料:
  • 问题是获取和数组中相应的索引,这些索引导致以较小的跳跃结束。例如:将需要s... 我说的跳跃是指跳跃;i、 e需要多少啤酒花。如果您是一个特定的索引,则可以通过该索引中的值进行跳跃。 下面是我在中的实现,它正确地给出了最小的跳转次数,但是我很难用

  • 问题声明:给定数组:[1,0,1,0,1,1,1,1,1,0,1,1,1,0]输出:到达结束所需的最小步骤 条件: 0上的步骤是退出 我已经完成了不使用DP的情况下的使用,是否存在针对此问题的DP解决方案。 我的代码:

  • 给定一个整数数组,其中每个元素表示可以从该元素向前执行的最大步数。编写一个函数,返回到达数组末尾(从第一个元素开始)的最小跳转次数。如果元素为0,则无法在该元素中移动。 输入: arr[] = { 1, 3, 5, 8, 9, 2, 6, 7, 6, 8, 9} 输出: 3(1- 发现了从动态规划方法到其他线性方法的多种方法。我无法理解所谓的时间线性方法。这里是一个链接,其中提出了一种线性方法。

  • 下面是寻找最小跳跃次数的算法谜题。发布了详细的问题声明和两个代码版本来解决这个问题。我做了测试,似乎两个版本都可以工作,我的第二个版本是版本一代码的优化版本,这使得我从开始,而不是持续增加,这可以通过不迭代所有的插槽来节省时间数组。 我的问题是,想知道我的第二个版本代码是否100%正确?如果有人发现任何逻辑问题,请指出。 问题陈述 给定一个非负整数数组,您最初位于数组的第一个索引处。 数组中的每个

  • 我有一个“使用递归到达数组末尾的最小跳跃次数”的代码。但我无法打印序列。(vector vec中没有可打印的内容) 如有任何帮助,将不胜感激。 说明: 我想以最小跳跃从数组的第一个元素(即2)到达最后一个元素(即4) 跳转的方式: 第一个元素是2。这意味着我最多可以在阵列中进行2次跳跃。如果我跳第一步,那么我可以跳到第二个元素(即3),或者如果我跳第二步,那么我可以跳到第三个元素(即1) 第二个元

  • 我处理下面提供的一个可编码性问题, 斐波那契序列使用以下递归公式定义: 一只小青蛙想去河的对岸。青蛙最初位于河的一边(位置−1),想要到达另一边(位置N)。青蛙可以跳过任何距离F(K),其中F(K)是第K个斐波那契数。幸运的是,河上有许多树叶,青蛙可以在树叶之间跳跃,但只能在N号位置的岸边方向跳跃。 河上的叶子用一个由N个整数组成的数组表示。数组A的连续元素表示从0到N的连续位置− 1在河上。阵列