Python 递归和动态规划的不同结果
正在解决以下问题 问题Python 递归和动态规划的不同结果,python,algorithm,python-2.7,Python,Algorithm,Python 2.7,正在解决以下问题 问题 from collections import defaultdict def move_up_right(remaining_right, remaining_up, prefix, result): if remaining_up == 0 and remaining_right == 0: result.append(''.join(prefix[:])) return if remaining_right >
from collections import defaultdict
def move_up_right(remaining_right, remaining_up, prefix, result):
if remaining_up == 0 and remaining_right == 0:
result.append(''.join(prefix[:]))
return
if remaining_right > 0:
prefix.append('r')
move_up_right(remaining_right-1, remaining_up, prefix, result)
prefix.pop(-1)
if remaining_up > 0:
prefix.append('u')
move_up_right(remaining_right, remaining_up-1, prefix, result)
prefix.pop(-1)
def move_up_right_v2(remaining_right, remaining_up):
# key is a tuple (given remaining_right, given remaining_up),
# value is solutions in terms of list
dp = defaultdict(list)
dp[(0,1)].append('u')
dp[(1,0)].append('r')
for right in range(1, remaining_right+1):
for up in range(1, remaining_up+1):
for s in dp[(right-1,up)]:
dp[(right,up)].append(s+'r')
for s in dp[(right,up-1)]:
dp[(right,up)].append(s+'u')
return dp[(right, up)]
if __name__ == "__main__":
result = []
move_up_right(2,3,[],result)
print result
print '============'
print move_up_right_v2(2,3)
给定一个m*n网格,其中一个允许向上或向右移动,找到两个网格点之间的不同路径
我写了一个递归版本和一个动态编程版本,但是它们返回不同的结果,有什么想法吗
源代码
from collections import defaultdict
def move_up_right(remaining_right, remaining_up, prefix, result):
if remaining_up == 0 and remaining_right == 0:
result.append(''.join(prefix[:]))
return
if remaining_right > 0:
prefix.append('r')
move_up_right(remaining_right-1, remaining_up, prefix, result)
prefix.pop(-1)
if remaining_up > 0:
prefix.append('u')
move_up_right(remaining_right, remaining_up-1, prefix, result)
prefix.pop(-1)
def move_up_right_v2(remaining_right, remaining_up):
# key is a tuple (given remaining_right, given remaining_up),
# value is solutions in terms of list
dp = defaultdict(list)
dp[(0,1)].append('u')
dp[(1,0)].append('r')
for right in range(1, remaining_right+1):
for up in range(1, remaining_up+1):
for s in dp[(right-1,up)]:
dp[(right,up)].append(s+'r')
for s in dp[(right,up-1)]:
dp[(right,up)].append(s+'u')
return dp[(right, up)]
if __name__ == "__main__":
result = []
move_up_right(2,3,[],result)
print result
print '============'
print move_up_right_v2(2,3)
动态编程版本的问题在于它没有考虑从多个向上移动(
'uu…'
)或多个向右移动('rr…'
)开始的路径
在执行主循环之前,您需要为从1
到剩余+1
的每个x
填充dp[(x,0)]
,并为从1
到剩余+1
的每个y
填充
换言之,替换为:
dp[(0,1)].append('u')
dp[(1,0)].append('r')
为此:
for right in range(1, remaining_right+1):
dp[(right,0)].append('r'*right)
for up in range(1, remaining_up+1):
dp[(0,up)].append('u'*up)
在版本2中,应该在0而不是1开始for循环。如果从1开始,则缺少可能的排列,即首先遍历最底部的行或最左侧的列
将版本2更改为:
def move_up_right_v2(remaining_right, remaining_up):
# key is a tuple (given remaining_right, given remaining_up),
# value is solutions in terms of list
dp = defaultdict(list)
dp[(0,1)].append('u')
dp[(1,0)].append('r')
for right in range(0, remaining_right+1):
for up in range(0, remaining_up+1):
for s in dp[(right-1,up)]:
dp[(right,up)].append(s+'r')
for s in dp[(right,up-1)]:
dp[(right,up)].append(s+'u')
return dp[(right, up)]
然后:
result = []
move_up_right(2,3,[],result)
set(move_up_right_v2(2,3)) == set(result)
True
只是为了好玩。。。另一种方法是:
from itertools import permutations
list(map(''.join, set(permutations('r'*2+'u'*3, 5))))
在问题中包含您的输入数据、输出数据和预期的输出数据可能会有所帮助。@Snakechermerb,我的输入数据包含在源代码中,请参见2,3,[],result
,即向右移动2步,向上移动3步。如果你对我原来的问题有什么想法,那就太好了。你还有什么希望呢?@greybeard,它已经很好了,谢谢你了。@greybeard,我对这个问题有了一些新的想法,我有了一个新的帖子,如果你有任何想法,那就太好了=>谢谢bunji的回复,投票并将其标记为答案。Grant bounty points.BTW,bunji,我对这个问题有一些新的想法,有一个新的帖子,如果你有任何想法,它会很棒=>BTW,user3290797,我对这个问题有一些新想法,有一个新帖子,如果你有任何想法,它会很棒=>