λ°±μ€€

λ°±μ€€ 27212 λ―ΈνŒ… - 파이썬

stoneeee 2023. 1. 14. 22:50



https://www.acmicpc.net/problem/27212

27212번: λ―ΈνŒ…

μ˜€λŠ˜μ€ AλŒ€ν•™μ˜ 학생 $N$λͺ…κ³Ό BλŒ€ν•™μ˜ 학생 $M$λͺ…이 λ§Œλ‚˜λŠ” 날이닀. 이듀이 λ§Œλ‚˜λŠ” μž₯μ†Œμ—λŠ” 크고 길이가 κΈ΄ 식탁이 ν•˜λ‚˜ μžˆμ–΄μ„œ, ν•œμͺ½μ—λŠ” AλŒ€ν•™ 학생이, λ‹€λ₯Έ ν•œμͺ½μ—λŠ” BλŒ€ν•™ 학생이 앉을 μ˜ˆμ •μ΄

www.acmicpc.net




μ•…μˆ˜ μ–˜κΈ°λ§Œ λ“€μ—ˆμ„ λ•ŒλŠ” 전깃쀄 λ¬Έμ œκ°€ λ– μ˜¬λžλŠ”λ° κ°‘μžκΈ° λ§Œμ‘±λ„λ₯Ό κ΅¬ν•˜λΌκ³  ν•œλ‹€.
DP둜 μ ‘κ·Όν•΄μ„œ ν•΄κ²°ν–ˆλ‹€.




dp[a][b]λŠ” AλŒ€ν•™ a번 학생이 BλŒ€ν•™μ—μ„œ b번 μ΄ν•˜μ˜ 학생과 μ•…μˆ˜λ₯Ό ν•  수 μžˆμ„ λ•Œ 얻을 수 μžˆλŠ” μ΄λ§Œμ‘±λ„μ˜ μ΅œλŒ“κ°’μœΌλ‘œ μ •ν–ˆλ‹€.

말이 μ΄μƒν•œλ°, 예λ₯Ό λ“€μ–΄ 문제의 예제λ₯Ό 살짝 λ³€ν˜•ν•΄μ„œ μ•„λž˜μ™€ 같은 쑰건이 μžˆλ‹€κ³  치자.

W = | 10   1 |
    |  1  10 |
    
A = [1, 2]
B = [1, 2, 2]



dp[1][1]은 A학ꡐ 1번 학생이 B학ꡐ 1번 μ΄ν•˜μ˜ 학생과 μ•…μˆ˜λ₯Ό ν•  수 μžˆμ„ λ•Œ 얻을 수 μžˆλŠ” λ§Œμ‘±λ„μ˜ μ΅œλŒ“κ°’μ΄λ‹€.
μ•…μˆ˜λ₯Ό μ•ˆ ν•˜λ©΄ λ§Œμ‘±λ„λŠ” 0, B학ꡐ 1번 학생과 μ•…μˆ˜λ₯Ό ν•œλ‹€λ©΄ λ§Œμ‘±λ„λŠ” 10이 될 것이닀.
λ”°λΌμ„œ dp[1][1] = 10이닀.


dp[1][2]λŠ” A학ꡐ 1번 학생이 B학ꡐ 2번 μ΄ν•˜μ˜ 학생과 μ•…μˆ˜λ₯Ό ν•  λ•Œ 얻을 수 μžˆλŠ” λ§Œμ‘±λ„μ˜ μ΅œλŒ“κ°’μ΄λ‹€.
B학ꡐ 2번과 μ•…μˆ˜λ₯Ό ν•œλ‹€λ©΄ λ§Œμ‘±λ„λŠ” 1이 λΌλ²„λ¦¬λ‹ˆ κ·Έλƒ₯ 1번 학생과 μ•…μˆ˜ν•˜λŠ” 편이 λ‚«λ‹€.
λ”°λΌμ„œ dp[1][2] μ—­μ‹œ 10이닀. dp[1][3]도 λ§ˆμ°¬κ°€μ§€λ‘œ 10이닀.



A학ꡐ 1번 학생이 μ•…μˆ˜λ₯Ό λ§ˆμ³€μœΌλ‹ˆ 2번 ν•™μƒμœΌλ‘œ λ„˜μ–΄κ°„λ‹€.

μ•…μˆ˜ν•˜λ©΄μ„œ νŒ”μ΄ 겹치면 μ•ˆ λ˜λ‹ˆ dp[2]λŠ” dp[1]에 λΉ„ν•΄ 좔가적인 쑰건듀을 κ³ λ €ν•΄μ£Όμ–΄μ•Ό ν•œλ‹€.
dp[2][1]을 ꡬ할 λ•Œ κ³ λ €ν•΄ 쀄 경우의 μˆ˜λŠ” 두 가지 정도이닀.

1) A학ꡐ 1번이 B학ꡐ 1번과 μ•…μˆ˜, A학ꡐ 2λ²ˆμ€ μ•…μˆ˜ μ•ˆ 함 > 10
2) A학ꡐ 1λ²ˆμ€ μ•…μˆ˜ μ•ˆ 함, A학ꡐ 2λ²ˆμ€ B학ꡐ 1번과 μ•…μˆ˜ > 1

λ”°λΌμ„œ dp[2][1]은 10이닀.




dp[2][2]λΆ€ν„°λŠ” μ„Έ 경우 쀑 ν•˜λ‚˜μ΄λ‹€.

1) A학ꡐ 2번이 B학ꡐ 2번과 μ•…μˆ˜ν•¨
> dp[2][2] = (A학ꡐ 1λ²ˆμ€ B학ꡐ 1번 μ΄ν•˜μ™€ μ•…μˆ˜ν•œ μ΅œλŒ“κ°’) + (μ§€κΈˆ μ•…μˆ˜μ˜ λ§Œμ‘±λ„) == dp[1][1] + 10 == 20
2) A학ꡐ 2번이 B학ꡐ 1번 μ΄ν•˜μ™€ μ•…μˆ˜ν•¨
> dp[2][2] = dp[2][1] == 1
3) A학ꡐ 2λ²ˆμ€ μ•…μˆ˜ μ•ˆ 함
> dp[2][2] = A학ꡐ 1번이 B학ꡐ 2번 μ΄ν•˜μ˜ 학생과 μ•…μˆ˜ν•œ μ΅œλŒ“κ°’ == dp[1][2] == 10

λ”°λΌμ„œ dp[2][2]λŠ” 20이닀.
이런 λ°©μ‹μœΌλ‘œ μ­‰ 경우의 수λ₯Ό κ³ λ €ν•΄μ„œ dpλ₯Ό μ±„μ›Œκ°€λ©΄ λœλ‹€.






μ„€λͺ…이 λ‘μ„œμ—†κ³  긴데...
μ •λ¦¬ν•΄μ„œ κ·œμΉ™μ„ μ°Ύμ•„λ³΄μžλ©΄, dp[a][b]λŠ” 크게 μ„Έ 가지 경우 쀑 ν•˜λ‚˜μ— ν•΄λ‹Ήν•  것이닀.

1) a번 학생이 b번 학생과 μ•…μˆ˜λ₯Ό 함
> dp[a][b] = dp[a-1][b-1] + (a와 bκ°€ μ•…μˆ˜ν•  λ•Œμ˜ λ§Œμ‘±λ„)
2) a번 학생이 b번 미만의 학생과 μ•…μˆ˜λ₯Ό 함
> dp[a][b-1]
3) a번 학생은 μ•…μˆ˜λ₯Ό μ•„μ˜ˆ μ•ˆ 함
> dp[a-1][b]

dp[a][b]에 1) ~ 3) 쀑 μ΅œλŒ“κ°’μ„ μ €μž₯ν•΄ μ£ΌλŠ” λ°©μ‹μœΌλ‘œ ν’€μ—ˆλ‹€.
κ·Έλ ‡λ‹€λ©΄ dp[N][M]이 λͺ¨λ“  경우의 수λ₯Ό κ³ λ €ν–ˆμ„ λ•Œ 얻을 수 μžˆλŠ” λ§Œμ‘±λ„μ˜ μ΅œλŒ“κ°’, 즉 정닡이닀.


N, M, C = map(int, input().split())
W = [list(map(int, input().split())) for _ in range(C)]

A = [0] + list(map(int, input().split()))
B = [0] + list(map(int, input().split()))

dp = [[0] * (M+1) for _ in range(N+1)]

for i in range(1, N+1):
    for j in range(1, M+1):
        dp[i][j] = max(max(dp[i-1][j-1] + W[A[i]-1][B[j]-1], dp[i][j-1]), dp[i-1][j])

print(dp[N][M])