白峻1520号:下り坂
2425 ワード
今日は白俊1520号の問題を解決しました.
1520号問題はDFSを利用して所与の高さの地図上で下り坂の個数を探す問題である.
問題の説明とI/Oフォーマット
I/O例
質問の回答(概要)
左上から右下までの下り坂数を知るために、下り坂条件を使用してDFSを行います.
例の2、3枚目の図から、経路が重なる可能性があり、時間の複雑さが増すことがわかります.そこで、ある点から到達点までの経路数hを配列に格納し、再びその点に到達したときにh値のみをとり、ブラウズを停止する方法(DP)が選択される.
Pythonコード
初めて問題を見たとき、問題は簡単だと思った.
単純にアレイの0,0点から,各点の上下左右にDFSを実行すれば,問題を解決できる.
そう考えて実施した結果、タイムアウトとなりました.
タイムアウト問題を解決するために,重複する可能性があるかどうかを考慮した.
多くの場合、シャベルで取り除いてみました
特定の経路で右下に到達した場合.
パスのあるポイントにアクセスすると、右下隅にも到達できることに気づきました.
例えば、例(50、45、37、32、20、17、15、10)の経路はhである.
hを通って右下の10に着きます.
以降hに到達する45,37,32,20,17,15のいずれかの地点では,hの経路に沿っていれば10に到達できるので,以降の経路を探知する必要はない.
そう思う.
まずMxN配列アクセスを作成する
経路hを介して右下隅に到達すると、経路hのすべての点にアクセスするのがtrueとなる.
また、DFSがアクセス値trueのポイントにアクセスすると、H値が1増加し、ブラウズが停止します.
問題は、実施後にテストケースを実行した結果、H値が答えより小さいことが分かったことです.
考えてみれば,アクセス値がtrueの場所では,到着点に通じる経路が2つ以上ある.したがって,配列アクセスをブール配列ではなくint配列に設定することで問題を解決できる.
1520号問題はDFSを利用して所与の高さの地図上で下り坂の個数を探す問題である.
問題の説明とI/Oフォーマット
I/O例
質問の回答(概要)
左上から右下までの下り坂数を知るために、下り坂条件を使用してDFSを行います.
例の2、3枚目の図から、経路が重なる可能性があり、時間の複雑さが増すことがわかります.そこで、ある点から到達点までの経路数hを配列に格納し、再びその点に到達したときにh値のみをとり、ブラウズを停止する方法(DP)が選択される.
from sys import stdin, setrecursionlimit
setrecursionlimit(10**6)
M, N = map(int, stdin.readline().rstrip().split())
m = []
for _ in range(M):
m.append(list(map(int, stdin.readline().rstrip().split())))
done = [[0] * N for _ in range(M)]
visited = [[False] * N for _ in range(M)]
def dfs(y, x):
now = m[y][x]
result = 0
if y == M-1 and x == N-1:
return 1
if y < M-1:
if m[y+1][x] < now:
if done[y+1][x] > 0:
result += done[y+1][x]
elif not visited[y+1][x]:
result += dfs(y+1, x)
if x < N-1:
if m[y][x+1] < now:
if done[y][x+1] > 0:
result += done[y][x+1]
elif not visited[y][x+1]:
result += dfs(y, x+1)
if y > 0:
if m[y-1][x] < now:
if done[y-1][x] > 0:
result += done[y-1][x]
elif not visited[y-1][x]:
result += dfs(y-1, x)
if x > 0:
if m[y][x-1] < now:
if done[y][x-1] > 0:
result += done[y][x-1]
elif not visited[y][x-1]:
result += dfs(y, x-1)
visited[y][x] = True
done[y][x] = result
return result
print(dfs(0, 0))
質問の回答(レビュー)初めて問題を見たとき、問題は簡単だと思った.
単純にアレイの0,0点から,各点の上下左右にDFSを実行すれば,問題を解決できる.
そう考えて実施した結果、タイムアウトとなりました.
タイムアウト問題を解決するために,重複する可能性があるかどうかを考慮した.
多くの場合、シャベルで取り除いてみました
特定の経路で右下に到達した場合.
パスのあるポイントにアクセスすると、右下隅にも到達できることに気づきました.
例えば、例(50、45、37、32、20、17、15、10)の経路はhである.
hを通って右下の10に着きます.
以降hに到達する45,37,32,20,17,15のいずれかの地点では,hの経路に沿っていれば10に到達できるので,以降の経路を探知する必要はない.
そう思う.
まずMxN配列アクセスを作成する
経路hを介して右下隅に到達すると、経路hのすべての点にアクセスするのがtrueとなる.
また、DFSがアクセス値trueのポイントにアクセスすると、H値が1増加し、ブラウズが停止します.
問題は、実施後にテストケースを実行した結果、H値が答えより小さいことが分かったことです.
考えてみれば,アクセス値がtrueの場所では,到着点に通じる経路が2つ以上ある.したがって,配列アクセスをブール配列ではなくint配列に設定することで問題を解決できる.
Reference
この問題について(白峻1520号:下り坂), 我々は、より多くの情報をここで見つけました https://velog.io/@rightafter/백준-1520번-내리막길テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol