ํŒŒ์ด์ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜

[๋ฐฑ์ค€ 10835] ์นด๋“œ๊ฒŒ์ž„ (Python) (๋งž์™œํ‹€)

์€์ง„ 2021. 9. 28. 02:13

๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป๋ฌธ์ œ๋งํฌ

[๋ฐฑ์ค€ 10835] ์นด๋“œ๊ฒŒ์ž„ (Python) (๋งž์™œํ‹€)
๋ฐฑ์ค€


โœ๏ธIdea Sketch

์–ธ์ œ๋“ ์ง€ ์™ผ์ชฝ ์นด๋“œ๋งŒ ํ†ต์— ๋ฒ„๋ฆด ์ˆ˜๋„ ์žˆ๊ณ  ์™ผ์ชฝ ์นด๋“œ์™€ ์˜ค๋ฅธ์ชฝ ์นด๋“œ๋ฅผ ๋‘˜ ๋‹ค ํ†ต์— ๋ฒ„๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๋•Œ ์–ป๋Š” ์ ์ˆ˜๋Š” ์—†๋‹ค.
์˜ค๋ฅธ์ชฝ ์นด๋“œ์— ์ ํžŒ ์ˆ˜๊ฐ€ ์™ผ์ชฝ ์นด๋“œ์— ์ ํžŒ ์ˆ˜๋ณด๋‹ค ์ž‘์€ ๊ฒฝ์šฐ์—๋Š” ์˜ค๋ฅธ์ชฝ ์นด๋“œ๋งŒ ํ†ต์— ๋ฒ„๋ฆด ์ˆ˜๋„ ์žˆ๋‹ค. ์˜ค๋ฅธ์ชฝ ์นด๋“œ๋งŒ ๋ฒ„๋ฆฌ๋Š” ๊ฒฝ์šฐ์—๋Š” ์˜ค๋ฅธ์ชฝ ์นด๋“œ์— ์ ํžŒ ์ˆ˜๋งŒํผ ์ ์ˆ˜๋ฅผ ์–ป๋Š”๋‹ค.


๋ฐฑ์ค€์„ ํ’€๋ฉด์„œ "๋งž์•˜์Šต๋‹ˆ๋‹ค!"๊ฐ€ ์•„๋‹ˆ๋ผ "**์ " ์ ์ˆ˜๋ฅผ ๋งค๊ฒจ์ฃผ๋Š” ๋ฌธ์ œ๋Š” ์ด ๋ฌธ์ œ๊ฐ€ ์ฒ˜์Œ์ด๋‹ค.
๋ฌธ์ œ๋ฅผ ํ’€๋ฉด์„œ ๋งž์™œํ‹€์„ ์ •๋ง ๋งŽ์ด ์™ธ์ณค๋‹ค.

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ Top-down ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค.
๋‹น์‹ ์ด 31์ ์ด๋ผ๋ฉด - ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ์—†์ด ๊ตฌํ˜„ํ–ˆ์„ ๊ฒƒ์ด๊ณ 
๋‹น์‹ ์ด 64์ ์ด๋ผ๋ฉด์ด๋ผ๋ฉด - sys.setrecursionlimit(10**6)์„ ์ƒ๋žตํ–ˆ๊ฑฐ๋‚˜ dp๋ฐฐ์—ด์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ–ˆ์„ ๊ฒƒ์ด๋‹ค.


๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป sys.setrecursionlimit()

Python์ด ์ •ํ•œ ์ตœ๋Œ€ ์žฌ๊ท€ ๊นŠ์ด๋ณด๋‹ค ์žฌ๊ท€์˜ ๊นŠ์ด๊ฐ€ ๋” ๊นŠ์–ด์ง€๋ฉด, RecursionError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
์ด ๊ฒฝ์šฐ ์ตœ๋Œ€ ์žฌ๊ท€ ๊นŠ์ด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.
BOJ ์ฑ„์  ์„œ๋ฒ„๋Š” ์ตœ๋Œ€ ์žฌ๊ท€ ๊นŠ์ด๊ฐ€ 1,000์ด๋‹ค.

  import sys
  sys.setrecursionlimit(10**6)

์ฐธ๊ณ 
https://help.acmicpc.net/judge/rte/RecursionError
https://fuzzysound.github.io/sys-setrecursionlimit




๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป ์ด ๋ฌธ์ œ๋Š” dp๋ฐฐ์—ด์„ -1๋กœ ์ดˆ๊ธฐํ™”ํ•ด์•ผํ•˜๋Š” ์ด์œ 

dp๋ฐฐ์—ด์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ  + ๋ฉ”๋ชจ์ด์ œ์ด์…˜์—์„œ 0์„ ํƒ์ƒ‰ ์œ ๋ฌด์˜ flag๋กœ ์“ฐ๋Š” ๊ฒฝ์šฐ ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธด๋‹ค.

  if dp[x][y] != 0:  # 0์ด ์•„๋‹Œ ๊ฒฝ์šฐ, ์ด๋ฏธ ํƒ์ƒ‰ํ–ˆ๋‹ค๊ณ  ํŒ๋‹จํ•˜์—ฌ dp๋ฐฐ์—ด์˜ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    return dp[x][y]

ํƒ์ƒ‰ ๊ฒฐ๊ณผ 0์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋ฏธ ํƒ์ƒ‰ํ–ˆ๋Š”๋ฐ๋„ dp๋ฐฐ์—ด์˜ ๊ฐ’์ด ๊ทธ๋Œ€๋กœ 0์ด๊ธฐ ๋•Œ๋ฌธ์—
ํƒ์ƒ‰๋˜์ง€ ์•Š์•˜๋‹ค๊ณ  ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋‹ค.
๋”ฐ๋ผ์„œ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ 
https://www.acmicpc.net/board/view/38906
https://www.acmicpc.net/board/view/15769




๐Ÿ‘ฉ๐Ÿปโ€๐Ÿ’ป ํ‘œ ๊ทธ๋ฆฌ๊ธฐ

์ด ๋ฌธ์ œ๋Š” ํ‘œ๋ฅผ ์ง์ ‘ ๊ทธ๋ ค๋ณด๊ณ  ๋‚˜์„œ์•ผ ์ œ๋Œ€๋กœ ์ดํ•ดํ–ˆ๋‹ค.
๋ฐฑ์ค€ ์˜ˆ์ œ ์ž…๋ ฅ 1๋ฒˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  3
  3 2 5
  2 4 1


dfs(์™ผ์ชฝ *๋ฒˆ์งธ ์นด๋“œ, ์˜ค๋ฅธ์ชฝ *๋ฒˆ์งธ ์นด๋“œ)
dfs(0, 0)์€ ์™ผ์ชฝ ์ฒซ๋ฒˆ์งธ ์นด๋“œ, ์˜ค๋ฅธ์ชฝ ์ฒซ๋ฒˆ์งธ ์นด๋“œ๋ฅผ ์˜๋ฏธํ•œ๋‹ค.

  dfs(0, 0) = dfs(0, 1) + 2                    # ์™ผ์ชฝ 3 > ์˜ค๋ฅธ์ชฝ 2 ์ด๋ฏ€๋กœ ์˜ค๋ฅธ์ชฝ 2 ๋ฒ„๋ฆฌ๊ณ  ์ ์ˆ˜ ํš๋“
  dfs(0, 1) = max(dfs(1, 1), dfs(1, 2))        # ์™ผ์ชฝ 3 < ์˜ค๋ฅธ์ชฝ 4 ์ด๋ฏ€๋กœ max(์™ผ์ชฝ ๋ฒ„๋ฆฌ๊ธฐ, ๋‘˜ ๋‹ค ๋ฒ„๋ฆฌ๊ธฐ) ๊ตฌํ•˜๊ธฐ
  dfs(1, 1) = max(dfs(2, 1), dfs(2, 2))        # ์™ผ์ชฝ 2 < ์˜ค๋ฅธ์ชฝ 4 ์ด๋ฏ€๋กœ max(์™ผ์ชฝ ๋ฒ„๋ฆฌ๊ธฐ, ๋‘˜ ๋‹ค ๋ฒ„๋ฆฌ๊ธฐ) ๊ตฌํ•˜๊ธฐ
  dfs(2, 1) = dfs(2, 2) + 4                    # ์™ผ์ชฝ 5 > ์˜ค๋ฅธ์ชฝ 4 ์ด๋ฏ€๋กœ ์˜ค๋ฅธ์ชฝ 4 ๋ฒ„๋ฆฌ๊ณ  ์ ์ˆ˜ ํš๋“
  dfs(2, 2) = dfs(2, 3) + 1                    # ์™ผ์ชฝ 5 > ์˜ค๋ฅธ์ชฝ 1 ์ด๋ฏ€๋กœ ์˜ค๋ฅธ์ชฝ 1 ๋ฒ„๋ฆฌ๊ณ  ์ ์ˆ˜ ํš๋“
  dfs(2, 3) = 0                                # ์˜ค๋ฅธ์ชฝ ๋„ค๋ฒˆ์งธ ์นด๋“œ๋Š” ์—†์œผ๋ฏ€๋กœ 0 ๋ฐ˜ํ™˜
  ...
  ๋”ฐ๋ผ์„œ dfs(2, 2) = dfs(2, 3) + 1 = 1
  dfs(2, 1) = dfs(2, 2) + 4 = 5
  dfs(1, 1) = max(dfs(2, 1), dfs(2, 2)) = max(5, 1) = 5
  ...(์ค‘๋žต)...
  ์œ„์™€ ๊ฐ™์€ ์—ฐ์‚ฐ ๊ณผ์ •์„ ๊ฑฐ์นœ๋‹ค.


right[y] 2 4 1
left[x] x \ y 0 1 2
3 0 7 5 -1
2 1 -1 5 1
5 2 -1 5 1

left๋Š” ์™ผ์ชฝ ๋”๋ฏธ ์นด๋“œ, right๋Š” ์˜ค๋ฅธ์ชฝ ๋”๋ฏธ ์นด๋“œ์ด๋‹ค.
x, y๋Š” ๊ฐ๊ฐ left, right์˜ ์ธ๋ฑ์Šค์ด๋ฉฐ 0๋ถ€ํ„ฐ ์‹œ์ž‘ํ•œ๋‹ค. 0์ด ์ฒซ๋ฒˆ์งธ ์นด๋“œ์ด๋‹ค.


โœ๏ธ์†Œ์Šค์ฝ”๋“œ

import sys
sys.setrecursionlimit(10**6)

def dfs(x, y):
  if x >= n or y >= n:
    return 0

  if dp[x][y] != -1:
    return dp[x][y]

  if left[x] > right[y]:
    dp[x][y] = dfs(x, y+1) + right[y]  # ์˜ค๋ฅธ์ชฝ ๋ฒ„๋ฆฌ๊ธฐ
  else:
    discard_left = dfs(x+1, y) 
    discard_both = dfs(x+1, y+1) 
    dp[x][y] = max(discard_left, discard_both)  # max(์™ผ์ชฝ ๋ฒ„๋ฆฌ๊ธฐ, ๋‘˜ ๋‹ค ๋ฒ„๋ฆฌ๊ธฐ)

  return dp[x][y]


if __name__ == "__main__":  
  n = int(input())
  left = list(map(int, sys.stdin.readline().rstrip().split()))
  right = list(map(int, sys.stdin.readline().rstrip().split()))

  dp = [[-1 for _ in range(n)] for _ in range(n)] 
  dfs(0, 0)
  print(dp[0][0])