[본 문제는 정확성과 효율성 테스트 각각 점수가 있는 문제입니다.]
당신은 코딩 테스트를 준비하기 위해 공부하려고 합니다. 코딩 테스트 문제를 풀기 위해서는 알고리즘에 대한 지식과 코드를 구현하는 능력이 필요합니다.
알고리즘에 대한 지식은 알고력
, 코드를 구현하는 능력은 코딩력
이라고 표현합니다. 알고력
과 코딩력
은 0 이상의 정수로 표현됩니다.
문제를 풀기 위해서는 문제가 요구하는 일정 이상의 알고력
과 코딩력
이 필요합니다.
예를 들어, 당신의 현재 알고력
이 15, 코딩력
이 10이라고 가정해보겠습니다.
풀 수 없는 문제를 해결하기 위해서는 알고력
과 코딩력
을 높여야 합니다. 알고력
과 코딩력
을 높이기 위한 다음과 같은 방법들이 있습니다.
알고력
을 높이기 위해 알고리즘 공부를 합니다. 알고력
1을 높이기 위해서 1의 시간이 필요합니다.코딩력
을 높이기 위해 코딩 공부를 합니다. 코딩력
1을 높이기 위해서 1의 시간이 필요합니다.알고력
과 코딩력
을 높입니다. 각 문제마다 문제를 풀면 올라가는 알고력과 코딩력이 정해져 있습니다.당신은 주어진 모든 문제들을 풀 수 있는 알고력
과 코딩력
을 얻는 최단시간을 구하려 합니다.
초기의 알고력
과 코딩력
을 담은 정수 alp
와 cop
, 문제의 정보를 담은 2차원 정수 배열 problems
가 매개변수로 주어졌을 때, 모든 문제들을 풀 수 있는 알고력
과 코딩력
을 얻는 최단시간을 return 하도록 solution 함수를 작성해주세요.
모든 문제들을 1번 이상씩 풀 필요는 없습니다. 입출력 예 설명을 참고해주세요.
알고력
을 나타내는 alp
와 초기의 코딩력
을 나타내는 cop
가 입력으로 주어집니다.alp
,cop
≤ 150problems
의 길이 ≤ 100problems
의 원소는 [alp_req
, cop_req
, alp_rwd
, cop_rwd
, cost
]의 형태로 이루어져 있습니다.alp_req
는 문제를 푸는데 필요한 알고력입니다.alp_req
≤ 150cop_req
는 문제를 푸는데 필요한 코딩력입니다.cop_req
≤ 150alp_rwd
는 문제를 풀었을 때 증가하는 알고력입니다.alp_rwd
≤ 30cop_rwd
는 문제를 풀었을 때 증가하는 코딩력입니다.cop_rwd
≤ 30cost
는 문제를 푸는데 드는 시간입니다.cost
≤ 100정확성 테스트 케이스 제한사항
alp
,cop
≤ 20problems
의 길이 ≤ 6alp_req
,cop_req
≤ 20alp_rwd
,cop_rwd
≤ 5cost
≤ 10효율성 테스트 케이스 제한사항
alp | cop | problems | result |
---|---|---|---|
10 | 10 | [[10,15,2,1,2],[20,20,3,3,4]] | 15 |
0 | 0 | [[0,0,2,1,2],[4,5,3,1,2],[4,11,4,0,2],[10,4,0,4,2]] | 13 |
이 문제는 DP 로 풀어야 한다.
이 문제 역시 처음에 방법은 떠올렸으나, 실제로 구현하지 못했다.
해당 해설을 참고하여 문제를 풀었다.
우리가 알고력과 코딩력을 키울 수 있는 방법은 총 3가지다.
1시간을 들여 알고력, 코딩력을 각각 늘리거나, 문제를 풀어서 문제의 보상으로 알고력, 코딩력을 늘리거나 이다.
문제가 바라는 것은 problems
의 모든 문제를 풀 수 있을 때까지의 최소 시간을 구하는 것이므로..
problems
가 요구하는 최대 알고력과 최대 코딩력을 찾는다.
최대값을 바탕으로 DP 테이블을 생성한다.
초기값은 무한대로 설정하여, 최소 시간을 구할 수 있도록 한다.
처음으로 시작하는 알고력과 코딩력을 제공 해주기 때문에, 시작지점은 0으로 초기화 한다.
max_alp
까지, max_cop
까지 for-loop
을 돌면서 최소 시간을 갱신한다.
# 알고력을 1 높이는 최소 시간, 현재값에 시간을 1 더하기 or 그대로 유지하기
DP[alp + 1][cop] = min(DP[alp + 1][cop], DP[alp][cop] + 1)
# 코딩력을 1 높이는 최소 시간, 현재값에 시간을 1 더하기 or 그대로 유지하기
DP[alp][cop + 1] = min(DP[alp][cop + 1], DP[alp][cop] + 1)
알고력과 코딩력을 단순히 1씩 증가시키는 방법은 위와 같다.
만약 풀 수 있는 문제들이 있다면
#problems의 원소는 [alp_req, cop_req, alp_rwd, cop_rwd, cost]의 형태로 이루어져 있습니다.
DP[alp + alp_rwd][cop_rwd] = min(DP[alp + alp_rwd][cop_rwd], DP[alp][cop] + cost)
이 문제에서 주의할 점은 인덱스 에러가 발생하지 않도록 경계값을 잘 설정해 주어야 한다.
첫번째로, 주어지는 알고력과 코딩력이 문제가 요구하는 알고력과 코딩력보다 높은 경우가 존재할 수 있다. → 이런 경우는 공부할 시간이 필요하지 않으므로 0을 리턴.
두번째로, 공부해서 얻는 알고력과 코딩력이 최대 알고력과 최대 코딩력보다 넘어갈 수 있다. → 이런 경우 DP 테이블의 범위에서 벗어나 인덱스 에러가 발생함.
그렇기 때문에 각각의 바운더리를 잘 설정해주어야 정확성 테스트 케이스에서 통과할 수 있다.
def solution(alp, cop, problems):
answer = 0
max_alp = max_cop = 0
for alp_req, cop_req, alp_rwd, cop_rwd, cost in problems:
max_alp = max(max_alp, alp_req)
max_cop = max(max_cop, cop_req)
alp = min(alp, max_alp)
cop = min(cop, max_cop)
times = [[float('inf') for _ in range(max_cop + 1)] for _ in range(max_alp + 1)]
times[alp][cop] = 0
for a in range(alp, max_alp + 1):
for c in range(cop, max_cop + 1):
if a + 1 <= max_alp:
times[a + 1][c] = min(times[a + 1][c], times[a][c] + 1)
if c + 1 <= max_cop:
times[a][c + 1] = min(times[a][c + 1], times[a][c] + 1)
for alp_req, cop_req, alp_rwd, cop_rwd, cost in problems:
if a >= alp_req and c >= cop_req:
na, nc = min(a + alp_rwd, max_alp), min(c + cop_rwd, max_cop)
times[na][nc] = min(times[na][nc],
times[a][c] + cost)
answer = times[max_alp][max_cop]
return answer