これは基本的に動的計画法の問題です。パスの詳細は将来の決定に影響しないため、各ステップで考えられるすべてのパスを考慮する必要はありません。各セルについて、特定の方向に移動し、特定の回数の移動を行った場合に収集できる最大量を知る必要があります。あなたの決定に影響を与えるものは他にありません。
def bestAmount(x,y,direction,n_moves):
# If this position is off the grid, then this isn't a valid state
if x<0 or x>=width or y>=height:
return None
if n_moves==0:
# We came to the last move.
if y!=height-1:
# If we're not at the bottom row then this isn't a valid path.
return None
# Otherwise, the final cell value is part of our total.
return cellValue(x,y)
if direction=='down':
# If we came down to get to this position, then the next move
# can be either left, right, or down
left = bestAmount(x-1,y,'left',n_moves-1)
right = bestAmount(x+1,y,'right',n_moves-1)
down = bestAmount(x,y+1,'down',n_moves-1)
return max(left,right,down)+cellValue(x,y)
if direction=='left':
# If we moved left to get to this position, then
# we can't go right, since we would be visiting the same position again.
left = bestAmount(x-1,y,'left',n_moves-1)
down = bestAmount(x,y+1,'down',n_moves-1)
return max(left,down)+cellValue(x,y)
if direction=='right':
# same logic as for left, but opposite.
right = bestAmount(x+1,y,'right',n_moves-1)
down = bestAmount(x,y+1,'down',n_moves-1)
return max(right,down)+cellValue(x,y)
def solve(n_moves):
# Start by pretending we entered the starting cell by going down
return bestAmount(0,0,'down',n_moves)
bestAmount がメモ化されている場合、可能性の数が比較的限られているため、かなり効率的なソリューションが得られます。
ただし、動的プログラミングの問題として扱うと、さらに効率的なソリューションが得られます。