''' 入力 N V SX SY GX GY L11 L21 L31 ⋯ LN1 L12 L22 L32 ⋯ LN2 ⋯ L1N L2N L3N ⋯ LNN 1行目に、砂漠の1辺の長さを表す整数 N (3≤N≤100)、 太郎君の体力値を表す整数 V (1≤V≤10000)、 太郎君の初期位置を表す整数の組 (SX,SY)(1≤SX,SY≤N)、 次の街の位置を表す整数の組 (GX,GY)(1≤GX,GY≤N)、 がスペース区切りで与えられます。 続くN行に、それぞれの場所の砂漠レベル LXY (0≤LXY≤9) が空白区切りで与えられます。 初期位置(SX,SY)と次の街の位置(GX,GY)は、同じ座標になることはありません。 出力 太郎君が死なずに、最も早く次の街へ着く最小の移動回数。 どうやっても生きてたどり着けない場合は −1 を出力すること。 最後に改行すること。 ''' import sys import heapq INF = 1e10 edgeLen,HP,startX,startY,goalX,goalY=map(int, input().split()) damages=[list(map(int, input().split())) for j in range(edgeLen)] damageSum=0 for y in range(edgeLen): for x in range(edgeLen): damageSum += damages[y][x] # print(edgeLen,HP,startX,startY,goalX,goalY) # print(damageSum) # 隣接ノード計算用 NextCoords=[(1,0),(0,1),(-1,0),(0,-1)] # 考えられる最大の体力 HP_consider_max = 9*edgeLen + 9*edgeLen if damageSum < HP or HP_consider_max < HP: # 一番近い距離で行けるはず print(abs(goalX-startX)+abs(goalY-startY)) sys.exit(0) # 座標と残体力に対するコストをメモ化 remainHP_Temp=[ [-1 for x_ in range(edgeLen)] for y_ in range(edgeLen)] remainHP=[ [-1 for x_ in range(edgeLen)] for y_ in range(edgeLen)] endOfStatus=[ [False for x_ in range(edgeLen)] for y_ in range(edgeLen)] # スタート位置を残体力MAXで初期化 remainHP[startY-1][startX-1] = HP for moveCount in range(1,edgeLen*2+1): # 1ループで1進むと見なせば良い? for y in range(edgeLen): for x in range(edgeLen): if remainHP[y][x] == -1: # print(x,y,damage,"=INF") continue for dx,dy in NextCoords: to_x,to_y=x+dx,y+dy if 0<=to_x", to_x, to_y, ":",minCostOfStatusTemp[to_y][to_x][hp - damages[to_y][to_x]] ) remainHP_Temp[to_y][to_x] = max( remainHP_Temp[to_y][to_x], remainHP[y][x] - damages[to_y][to_x] ) if 0 < remainHP_Temp[goalY-1][goalX-1]: print(moveCount) sys.exit(0) endOfStatus[y][x]=True remainHP = remainHP_Temp #.copy() remainHP_Temp=[ [-1 for x_ in range(edgeLen)] for y_ in range(edgeLen)] # 見つからなかった print(-1)