我想找到通过2D整数数组的路径(没有负数,大小为N * N),其中所有传递的数字的总和最接近给定的数字。从左上角开始,在导航数组的每个步骤中,您只能向下或向右移动。目的地是阵列的右下角。
示例:
field = [
[0,5,1],
[1,3,5]
[2,1,1]
]
n = 5
solution(field, n) => 0
// down, down, right, right
solution(field, 7) => 1
如果找不到解决方案,则产生正数,则返回-1
。
我的低效解决方案:
def solution(n, field)
res = closest(n, field)
if res < 0:
return -1
return res
def closest(n, field)
best = n - field[0][0]
if len(field) > 1:
"Remove upper most row and call recursively"
tmp = solution(n - field[0][0], field[1:])
if tmp >= 0:
best = tmp
if len(field[0]) > 1:
"Remove left most column and call recursively"
tmp = solution(n - field[0][0], [(x[0:0] + x[1:]) for x in field])
if tmp < best:
best = tmp
return best
这适用于小型领域,但效率极低。 对于包含20列和20行的字段,找到解决方案需要很长时间。
有没有更有效的方法来解决这个问题。 (即20 * 20几秒钟) (代码不必在python中
答案 0 :(得分:2)
您可以使用动态编程或memoization来有效地解决此问题。首先,递归函数的表达方式如下:
C(x, y, n) = -1 if x < 0 or y < 0 or x >= n or y >= n or n < 0 (1)
| field[x][y] if x = n - 1 and y = n - 1 and n >= 0 (2)
| -1 if FromUp = -1 and FromLeft = -1 (3)
| field[x][y] + Max(FromUp, FromLeft) (4)
where C(x, y, n) is the length of the path closest to n ending at x and y
FromLeft = C(x - 1, y, n - field[x][y])
FromUp = C(x, y - 1, n - field[x][y])
有2个基本情况(1)和(2),(1)表示无效的行或列或n。 (2)表示您已经使用有效的n到达右下角的单元格。对于特定的x,y和n,您可以来自上部单元格或左侧单元格。因此(3)是失败的递归情况,(4)如果递归情况中的1个成功,则计算C(x,y,n)的正确长度。
如果您想使用动态编程,您可以构建一个3D表并用3个嵌套for循环填充它。如果你想使用memoization,只需编写上面的递归函数;但每次返回某些内容时,请将其记录在3D表格中,然后在其他步骤之前尝试使用该表格中的结果
答案 1 :(得分:0)
我认为你正在寻找这个
F = [[0,5,1],
[1,3,5],
[2,1,1]]
N = 3
SUM = [[0 for x in range(N)] for y in range(N)]
n = 7
def solution(row, col):
if row==N or col==N :
return 10**10;
if row==N-1 and col==N-1:
return F[row][col]
if(SUM[row][col]):
return SUM[row][col]
A = solution(row+1, col) + F[row][col]
B = solution(row, col+1) + F[row][col]
if(abs(n-A)<=abs(n-B)):
SUM[row][col] = A
else:
SUM[row][col] = B
return SUM[row][col]
def RES(n):
res = solution(0,0)
if(res<0):
return -1
else:
return abs(res-n)
print RES(n)