值列表跳转单元格以查找最便宜的路径(输出不正确)

时间:2018-02-13 23:37:12

标签: python list recursion logic calculation

我有一个应该玩Jump it游戏的程序。我被赋予了价值,并且必须以最便宜的方式递归地移动值。我可以跳到相邻的小区,也可以跳到那个小区。我的计划如下:

def jumpIt(n, k, lst):
    sums = []
    #sums will collect the 'cost' of the game in a list
    if (k > n-1):
        #first base case if the list if the length is 0
        return 0
    elif (k+1 > n-1):
        #2nd base case if the list is two cells
        return lst[k]
    else: 
        if (lst[k] < lst[k+1]):
            sums.append(lst[k])
            #if the cell of K is less than k+1 computes:
            return lst[k] + jumpIt(n, k+2, lst) 
        else:
            sums.append(lst[k+1])
            return lst[k+1] + jumpIt(n, k+2, lst)



def main(): 
    #list to sum the cost of each move 
    fileName = "input.txt"
    for line in open(fileName):
        lst = line.split()
        lst = [int(x) for x in lst]
        print(jumpIt(len(lst),1,lst))

main()

输入为

0 3 80 6 57 10
0 98 7 44 25 3 5 85 46 4
0 57 59 83 9 42 70
0 20 49 96 53 7 43 77
0 24 17 15 61 49 8 65 43 26 99 7 57 97 50 93 6 82 52

并且正确的输出假设为:

19
87
138
186
330

然而,使用我给定的代码,我收到的输出是

19
85
108
157
224

我不知道为什么这样做有人可以帮忙吗?

3 个答案:

答案 0 :(得分:0)

我不确定为什么你的程序会返回它的功能。也许你可以一步一步地记录,看看发生了什么 - 一个好的候选人可能是短序列0 57 59 83 9 42 70,在那里你可以看到答案偏离预期的输出。如果我们知道&#34;那么每个单元格都会从后面一两步到达。哪一个最好提前我们可以选择那一个。幸运的是,我们可以使用递归回溯:

def f(lst):
  def g(i):
    if i < 0:
      return 0
    return lst[i] + min(g(i-1), g(i-2))

  return g(len(lst) - 1)

print f([0, 24, 17, 15, 61, 49, 8, 65, 43, 26, 99, 7, 57, 97, 50, 93, 6, 82, 52])
# 327 => sum [0, 17, 61, 8, 43, 26, 7, 57, 50, 6, 52]

答案 1 :(得分:0)

class small:
    smallest = 100000

def jumpIt(k, lst, total, s):   
    if(k + 1 < len(lst)):
        jumpIt(k + 1, lst, total + lst[k + 1], s)
    if(k + 2 < len(lst)):
        jumpIt(k + 2, lst, total + lst[k + 2], s)
    if(k + 1>= len(lst) and total < s.smallest):
        s.smallest = total

def main():
    #list to sum the cost of each move
    fileName = "input.txt"
    s = small()
    for line in open(fileName):
        lst = line.split()
        lst = [int(x) for x in lst]
        jumpIt(0, lst, 0, s)
        print(s.smallest)
        s.smallest = 100000
main()
  

输出:19 87 138 186 327

这是我的解决方案,它生成正确的输出并使用对象来跟踪全局最小值。这是一个测试,但您可能希望将最小值设置为整数最大值或数组之和或类似的

说明: 在每次通话时,我先检查是否超出阵列的界限,如果不是,我会采取措施。一旦我到达终点,我检查我所采用的路径是否是最小的,如果是我更新当前路径。通过使用一个对象,我可以确保我所获得的最小值将是所有递归调用的最小值

答案 2 :(得分:-1)

根据我的理解,如果该行是

[0 98 7 44 25 3 5 85 46 4]

然后步骤将是:

7跳转到min(98,7)==7,然后从25跳转到min(44,25)==25,然后从3开始跳转到min(3,5)==3 ,然后再从5开始一次跳转到min(5,85)==5,依此类推......所以总和将为90

这是我的版本..没有递归:

lines = ["0 3 80 6 57 10", \
         "0 98 7 44 25 3 5 85 46 4", \
        "0 57 59 83 9 42 70", \
        "0 20 49 96 53 7 43 77", \
        "0 24 17 15 61 49 8 65 43 26 99 7 57 97 50 93 6 82 52"];


def JumpIt_no_recs (lst):
    expense = 0; 
    index = 0;
    while (index < len(lst)):
         two_num = lst[index+1:index+3];
         try:
             minimum = min(two_num); 
         except:
             break;
         jump = two_num.index(minimum)+1;  
         index = index+jump;
         expense += minimum;
    return expense

for line in lines:
    lst = [int(num) for num in line.split()];
    print(JumpIt(lst));

另一个版本,带递归..

def JumpIt(lst, idx1, idx2, expense):
     two_num = lst[idx1:idx2];
     try:
         minimum = min(two_num); 
     except:
         return expense;
     jump = two_num.index(minimum)+1;  
     expense += minimum;
     idx1+=jump; idx2+=jump;
     return JumpIt(lst, idx1, idx2, expense);

for line in lines:
    lst = [int(num) for num in line.split()];
    print(JumpIt(lst, 1, 3, 0));

输出为:19,90,237,249,330