[Algorithm] ๐Ÿšฉ[๋ฐฑ์ค€] 2167 (Feat. DP, ๋™์ ๊ณ„ํš๋ฒ•)

myeonjiยท2022๋…„ 2์›” 5์ผ
0

Algorithm

๋ชฉ๋ก ๋ณด๊ธฐ
34/89

> ๋™์ ๊ณ„ํš๋ฒ• (Dynamic Programming)

ํ•œ ๋ฒˆ ๊ณ„์‚ฐ๋œ ๋ฌธ์ œ๋Š” ๋‹ค์‹œ ๊ณ„์‚ฐํ•˜์ง€ ์•Š๋„๋ก ํ•œ๋‹ค.

  • ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ ์ ˆํžˆ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰ ์‹œ๊ฐ„ ํšจ์œจ์„ฑ์„ ๋น„์•ฝ์ ์œผ๋กœ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•
  • ์ด๋ฏธ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ(์ž‘์€ ๋ฌธ์ œ)๋Š” ๋ณ„๋„์˜ ๋ฉ”๋ชจ๋ฆฌ ์˜์—ญ์— ์ €์žฅํ•˜์—ฌ ๋‹ค์‹œ ๊ณ„์‚ฐX
  • ์‚ฌ์šฉ ์กฐ๊ฑด
  1. ์ตœ์  ๋ถ€๋ถ„ ๊ตฌ์กฐ(Optimal Substructure) : ํฐ ๋ฌธ์ œ๋ฅผ ์ž‘์€ ๋ฌธ์ œ๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ž‘์€ ๋ฌธ์ œ์˜ ๋‹ต์„ ๋ชจ์•„์„œ ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐ ํ•  ์ˆ˜ ์žˆ๋‹ค.
  2. ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ(Overlapping Subproblem) : ๋™์ผํ•œ ์ž‘์€ ๋ฌธ์ œ๋ฅผ ๋ฐ˜๋ณต์ ์œผ๋กœ ํ•ด๊ฒฐํ•ด์•ผ ํ•œ๋‹ค.
  • ๋Œ€ํ‘œ์ ์ธ ์˜ˆ์‹œ : ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด
    ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์—ด์˜ ์žฌ๊ท€์  ํ’€์ด๋Š” O(2^n)์ด๊ณ , ๋‹จ์ˆœ ๋ฐ˜๋ณต ํ’€์ด๋Š” O(N) ์ด๋‹ค.
    ์žฌ๊ท€ ํ•จ์ˆ˜๋กœ ํ•ด๊ฒฐํ•˜๋ฉด, ์ค‘๋ณต๋˜๋Š” ๋ถ€๋ถ„ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋Š” ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์œผ๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

1. Memoization (Top-Down, ํ•˜ํ–ฅ์‹) : ํฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด์„œ ์ž‘์€ ๋ฌธ์ œ๋“ค์„ ์žฌ๊ท€์ ์œผ๋กœ ํ˜ธ์ถœํ•˜์—ฌ ํฐ ๋ฌธ์ œ์— ๋Œ€ํ•œ ๋‹ต์„ ์–ป์Œ

  • ํ•œ ๋ฒˆ ๊ณ„์‚ฐํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ๋ฆฌ ๊ณต๊ฐ„์— ๋ฉ”๋ชจ
  • ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ”๋ชจํ–ˆ๋˜ ๊ฒฐ๊ณผ ๊ฐ€์ ธ์˜ค๊ธฐ
  • ๊ฐ’์„ ๊ธฐ๋กํ•ด ๋†“๋Š”๋‹ค๋Š” ์ ์—์„œ ์บ์‹ฑ(Caching)์ด๋ผ๊ณ ๋„ ํ•จ
# Memoization (Top-Down, ํ•˜ํ–ฅ์‹)

# ํ•œ ๋ฒˆ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฉ”๋ชจ์ด์ œ์ด์…˜ ํ•˜๊ธฐ ์œ„ํ•œ ๋ฆฌ์ŠคํŠธ ์ดˆ๊ธฐํ™”
d = [0]*100 

# ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜๋ฅผ ์žฌ๊ท€ํ•จ์ˆ˜๋กœ ๊ตฌํ˜„(ํƒ‘๋‹ค์šด ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ)
def fibo(x):
   	# ์ข…๋ฃŒ ์กฐ๊ฑด(1 ํ˜น์€ 2์ผ ๋•Œ 1์„ ๋ฐ˜ํ™˜)
    if x == 1 or x == 2:
    	return 1
    # ์ด๋ฏธ ๊ณ„์‚ฐํ•œ ์  ์žˆ๋Š” ๋ฌธ์ œ๋ผ๋ฉด ๊ทธ๋Œ€๋กœ ๋ฐ˜ํ™˜
    if d[x] != 0:
    	return d[x]
    # ๋งŒ์•ฝ ๊ณ„์‚ฐํ•œ ์ ์ด ์—†๋‹ค๋ฉด ์ ํ™”์‹์— ๋”ฐ๋ผ์„œ ํ”ผ๋ณด๋‚˜์น˜ ๊ฒฐ๊ณผ ๋ฐ˜ํ™˜
    d[x] = fibo(x-1) + fibo(x-2)
    return d[x]

print(fibo(99))

๐Ÿ’ก 2. Tabulation (Bottom-up, ์ƒํ–ฅ์‹) : ๋‹จ์ˆœ ๋ฐ˜๋ณต๋ฌธ ์ด์šฉ

  • ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ์ „ํ˜•์ ์ธ ํ˜•ํƒœ
# Tabulation (Bottom-up, ์ƒํ–ฅ์‹)

# ์•ž์„œ ๊ณ„์‚ฐ๋œ ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๊ธฐ ์œ„ํ•œ DP ํ…Œ์ด๋ธ” ์ดˆ๊ธฐํ™”
d = [0] * 100

# ์ฒซ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜์™€ ๋‘ ๋ฒˆ์งธ ํ”ผ๋ณด๋‚˜์น˜ ์ˆ˜๋Š” 1
d[1] = 1
d[2] = 1
n = 99

# ํ”ผ๋ณด๋‚˜์น˜ ํ•จ์ˆ˜ ๋ฐ˜๋ณต๋ฌธ์œผ๋กœ ๊ตฌํ˜„
for i in range(3, n+1):
	d[i] = d[i - 1] + d[i - 2]
    
print(d[n])

<์ฒ˜์Œ ์‹œ๋„>

n, m = map(int, input().split())
tot = [list(map(int, input().split())) for _ in range(n)]
k = int(input())


def solution(tot):
    i, j, x, y = map(int, input().split())
    sum = 0
    for a in range(i, x+1):
        for b in range(j, y+1):
            sum += tot[a-1][b-1]

    return sum


for _ in range(k):
    print(solution(tot))

์‹œ๊ฐ„ ์ œํ•œ 2์ดˆ์ด๊ณ  ์‹œ๊ฐ„ ๋ณต์žก๋„ O(N^2)์ธ ๊ฒƒ ๊ฐ™์€๋ฐ ์™œ ์‹œ๊ฐ„์ดˆ๊ณผ๊ฐ€ ์ƒ๊ธธ๊นŒ?
-> ์•„.. ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋‹ˆ๊นŒ ์‹œ๊ฐ„ ๋ณต์žก๋„๊ฐ€ O(N^3)์ด๊ฒ ๊ตฌ๋‚˜.. ํฐ ์ฐฉ๊ฐ์„..

<์žฌ์‹œ๋„>

n, m = map(int, input().split())
lst = [list(map(int, input().split())) for _ in range(n)]

# ๋ˆ„์ ํ•ฉ ํ…Œ์ด๋ธ” ๋งŒ๋“ค๊ธฐ
dp = [[0]*(m+1) for _ in range(n+1)]
for a in range(1, n+1):
    for b in range(1, m+1):
        dp[a][b] = lst[a-1][b-1] + dp[a][b-1] + dp[a-1][b] - dp[a-1][b-1]

k = int(input())
for _ in range(k):
    i, j, x, y = map(int, input().split())
    print(dp[x][y] - dp[x][j-1] - dp[i-1][y] + dp[i-1][j-1])

์ดํ•ดํ•˜๋Š”๋ฐ ์ฐธ๊ณ ํ•œ ์ž๋ฃŒ

profile
๐Ÿ“š

0๊ฐœ์˜ ๋Œ“๊ธ€