코팅테스트/코딩테스트 이론 정리

8-2. DP(다이나믹동적계획법) 문제2

유지광이 2021. 8. 20. 15:38
728x90

정답 코드

#정수 N,M을 입력 받기
n,m = map(int, input().split())
#N개의 화페 단위 정보를 입력받기
array = []
for i in range(n):
    array.append(int(input()))

#한번 계산된 결과를 저장하기 위한 DP테이블 초기화
d = [10001] * (m+1)

#다이나믹 프로그래밍 진행(바텀업)
d[0] = 0
for i in range(n):
    for j in range(array[i], m+1):
        if d[j - array[i]] != 10001: #(i-k)원을 만드는 방법이 존재하는 경우
            d[j] = min(d[j],d[j-array[i]]+1)

#계산된 결과 출력
if d[m] == 10001: #최종적으로 M원을 만드는 방법이 없는 경우
    print(-1)
else:
    print(d[m])

금광 문제

정답 코드

#테스트 케이스 입력
t = int(input())

for _ in range(t):
    #금광 정보 입력
    n, m = map(int, input().split())
    array = list(map(int,input().split()))
    #다이나믹 프로그래밍을 위한 2차원 DP테이블 초기화
    dp = []
    index = 0
    result = 0
    for i in range(n):
        dp.append(array[index:index+m])
        index += m
    #다이나믹 프로그래밍 진행
    for j in range(1,m): #열
        for i in range(n): #행
            # 왼쪽 위에서 오는 경우
            if i == 0: left_up =0
            else:left_up = dp[i-1][j-1]
            #왼쪽 아래에서 오는 경우
            if i == n - 1: left_down = 0
            else:left_down = dp[i+1][j-1]
            # 왼쪽에서 오는 경우
            left = dp[i][j-1]
            #2번째 열부터 전 열에서 온 값 + 왼쪽위,왼쪽아래,왼쪽 중 가장 큰값을 더한다.
            dp[i][j] = dp[i][j] + max(left_up,left_down,left)

    for i in range(n):
        result = max(result,dp[i][m-1])
    print(result)

문제3 병사 배치하기

나의 코드

n = int(input())
array = list(map(int,input().split()))

result = 0
for i in range(n):
    if i != n-1:
        if(array[i] < array[i+1]):
            result += 1
print(result)

정답 코드

n = int(input())

array = list(map(int,input().split()))
#순서를 뒤집어 '최장 증가 부분 수열' 문제로 전환
#array.reverse() #밑에서 부호를 if array[j] > array[i]: 로 설정해도 가능

#DP를 위한 1차원 DP테이블 초기화
dp = [1] * n

#가장 긴 증가하는 부분 수열(LIS) 알고리즘 수행
for i in range(1,n):
    for j in range(0,i):
        if array[j] > array[i]:
            dp[i] = max(dp[i],dp[j]+1) #dp[i] = dp[j+1] 도가능
print(dp)
#열외해야 하는 병사의 최소 수를 출력
print(n-max(dp))

 

728x90