[알고리즘] 최대점수 구하기(냅색 알고리즘)
(문제) 최대점수 구하기(냅색 알고리즘)
이번 정보올림피아드대회에서 좋은 성적을 내기 위하여 현수는 선생님이 주신 N개의 문제를 풀려고 합니다.
각 문제는 그것을 풀었을 때 얻는 점수와 푸는데 걸리는 시간이 주어지게 됩니다.
제한시간 M안에 N개의 문제 중 최대점수를 얻을 수 있도록 해야 합니다.
(해당문제는 해당시간이 걸리면 푸는 걸로 간주한다, 한 유형당 한개만 풀 수 있습니다.)
입력설명
첫 번째 줄에 문제의 개수N(1<=N<=100)과 제한 시간 M(10<=M<=1000)이 주어집니다.
두 번째 줄부터 N줄에 걸쳐 문제를 풀었을 때의 점수와 푸는데 걸리는 시간이 주어집니다.
출력설명
첫 번째 줄에 제한 시간안에 얻을 수 있는 최대 점수를 출력합니다.
테스트케이스
입력예제 | 출력예제 |
---|---|
5 20 10 5 25 12 15 8 6 3 7 4 |
41 |
9 50 12 7 16 8 20 10 30 15 10 5 25 12 15 8 6 3 7 4 |
101 |
12 70 5 2 11 5 12 7 16 8 20 10 30 15 10 5 25 12 15 8 6 3 7 4 3 2 |
141 |
해결방법
최대로 중복 이용해서 값을 구할 경우 –> 정 . 방 . 향 (최고 방법)
최대로 중복 없이 이용해서 값을 구할 경우 –> 반 . 대 . 방 . 향 (최고 방법)
최대로 중복 없이 이용해서 값을 구할 경우 –> 정 . 방 . 향 . 2 . 차 . 원 . 배 . 열
방법 1 ) 2차원 배열을 이용한 다이나믹 테이블
방법 2 ) 1차원 배열을 이용한 다이나믹 테이블
코드
2차원 배열 방식
n, m = map(int, input().split())
# 문제[?][0] : 점수
# 문제[?][1] : 걸리는 시간
questions = [list(map(int, input().split())) for _ in range(n)]
# X분 안에 걸리는 시간의 최대 점수가 각 X 인덱스 안에 들어간다.
dt = [[0] * (m + 1) for _ in range(n + 1)]
# 한 유형당 한개만 풀 수 있다 (중복 불가능)
# 2 차원 테이블에서 생각
# 행은 유형의 종류
# 열은 들어갈 수 있는 최대 점수의 경우
for idx, question in enumerate(questions):
for j in range(question[1], m + 1):
# 전의 유형에서 걸리는 시간의 최대 점수 값을 넣은 인덱스 비교하여
# 값이 큰 것을 현재 유형의 걸리는 시간 인덱스에 할당
dt[idx+1][j] = max(dt[idx][j], dt[idx][j-question[1]] + question[0])
print(dt[-1][-1])
1차원 배열 방식
# 2 차원을 이용해서 하면 시간 복잡도 문제가 생길 수 있다고 한다.
# 1 차원으로 하는 경우 (반대로 값을 채우기 시작한다!)
n, m = map(int, input().split())
# 문제[?][0] : 점수
# 문제[?][1] : 걸리는 시간
questions = [list(map(int, input().split())) for _ in range(n)]
# X분 안에 걸리는 시간의 최대 점수가 각 X 인덱스 안에 들어간다.
dt = [0] * (m + 1)
for question in questions:
# 뒤쪽에서 시작하여 온다
for j in range(m, question[1]-1, -1):
if dt[j] < dt[j-question[1]] + question[0]:
dt[j] = dt[j-question[1]] + question[0]
print(dt[-1])
댓글남기기