python中的备忘录化,逐个错误

python中的备忘录化,逐个错误,python,algorithm,runtime-error,Python,Algorithm,Runtime Error,我目前正在上算法课。我正在用python测试它们,包括动态编程。下面是一个自下而上的杆切割实现 它不工作,因为关闭一个错误。python中是否有一个全局设置,可以将默认数组索引更改为1而不是0?或者有人能为我提供一个更好的策略来克服我遇到过无数次的错误。真烦人 def bottom_up_memo_cut_rod(p,n): r = [ 0 for i in range(n) ] r[0] = 0 for j in range(n): q = -1

我目前正在上算法课。我正在用python测试它们,包括动态编程。下面是一个自下而上的杆切割实现

它不工作,因为关闭一个错误。python中是否有一个全局设置,可以将默认数组索引更改为1而不是0?或者有人能为我提供一个更好的策略来克服我遇到过无数次的错误。真烦人

def bottom_up_memo_cut_rod(p,n):
    r = [ 0 for i in range(n) ]
    r[0] = 0
    for j in range(n):
        q = -1
        for i in range(j):
            q = max(q, p[i] + r[j-i])
        r[j] = q
    return r[n]

bottom_up_memo_cut_rod([1,5,8,9], 4)

答案应该是10,在这种情况下,将4分为(2,2)会产生10的最高价格。

Python中有一些东西可以帮助您。内置的
enumerate
是一个很好的工具

for idx, val_at_idx in enumerate(aList):
  # idx is the 0-indexed position, val_at_idx is the actual value.
如果绝对必要,您还可以使用带有枚举的列表切片来移动索引:

for idxOffBy1, val_at_wrong_idx in enumerate(aList[1:]):
  # idx here will be 0, but the value will be be from position 1 in the original list.

但实际上,您不想尝试更改解释器,使列表从索引1开始。您需要调整算法以使用该语言。

在您的情况下,关闭1是
r[n]
的结果,其中
len(r)==n
。您可以编写
r[n-1]
,或者更优选地编写
r[-1]
,这意味着“r的最后一个元素”,同样的
r[-2]
将意味着“倒数第二个”等


不相关但很有用:
[0 for i in range(n)]
可以写成
[0]*n
在Python中,通常可以避免使用索引。该算法可以这样编写:

def bottom_up_memo_cut_rod(p,n):
    r = [0]
    for dummy in p:
        r.append(max(a + b for a, b in zip(reversed(r),p)))
    return r[-1]

print bottom_up_memo_cut_rod([1,5,8,9], 4)
#10

但是在使用[x]*n语法时要小心。在处理可变类型时为True。事实上,
[[]]*3
将创建对同一列表的引用列表,因此,
lst[0]。append(1)
将为
[[1]、[1]、[1]]
+1表示
枚举()。在Python2.6及更高版本中,
enumerate()
为起始索引增加了一个参数,这在处理基于1的对象时可能会有所帮助。这是一个不错的解决方案。但我想知道基于插入的版本是否比原始版本更可取。用
反向
迭代列表是O(1),但在列表开头插入是O(n)。从长远来看,这并不要紧,因为整个算法是O(n** 2),但我猜想使用插入是慢的一个常数倍数。您也可以考虑使用<代码> DeQue>代码>,而不是<代码>列表。那么前面的插入将是O(1)。