문제
유니스트 컴퓨터공학과에 다니는 서윤이는 이번에 어떤 과목을 들을지 고민중이다. 학점을 잘 받을 수 있으면서도 중요한 과목을 듣고 싶은 서윤이는 모든 과목의 중요도와, 일정 이상의 학점을 받기 위해 필요한 공부시간을 다 적었다.
처음에는 모든 과목을 들으려고 했던 서윤이는 자신의 공부 시간에 한계가 있다는 것을 깨달았다. 그래서, 공부 시간의 한계를 초과하지 않으면서 과목의 중요도 합이 최대가 되도록 몇 개만 선택하여 수강하기로 마음먹었다.
중요도가 최대가 되도록 과목을 선택했을 때, 최대가 되는 중요도를 출력하는 프로그램을 작성하시오.
입력
첫줄에 서윤이의 최대 공부시간 N (1 ≤ N ≤ 10,000), 과목 수 K (1 ≤ K ≤ 1,000)이 공백을 사이에 두고 주어진다.
이후 K개의 줄에 중요도 I (1 ≤ I ≤ 100,000), 필요한 공부시간 (1 ≤ T ≤ 10,000)이 공백을 사이에 두고 주어진다.
출력
얻을 수 있는 최대 중요도를 출력한다.
문제 풀이
평범한 배낭 문제.
2차원 dp 배열을 선언한 후, i번째 과목까지에 대해 j시간에 얻을 수 있는 최대 중요도를 구한다. j가 i번째 과목에 필요한 공부 시간보다 작으면, i번째 과목을 공부할 수 없으므로, dp[i][j]는 i-1번째 과목까지에 대해 j 시간에 얻을 수 있는 최대 중요도가 된다. 즉, dp[i][j]=dp[i-1][j]이다.
j가 i번째 과목에 필요한 공부 시간보다 크거나 같으면, i번째 과목을 공부할 수도 있고, i번째 과목을 공부하지 않을 수도 있다. 만약 i번째 과목을 공부한다면, i-1번째 과목까지에 대해 j - (i번째 과목의 필요 공부 시간) 만큼 중요도를 얻은 후, i번째 과목의 필요 공부 시간만큼의 중요도를 얻으면 된다. i번째 과목의 필요 공부 시간을 studyTime, 중요도를 importance라 한다면, dp[i][j] = dp[i-1][j-studyTime] + importance가 된다.
i번째 과목에 대해 공부하지 않으면, i-1번째 과목까지에 대해 j 시간에 얻을 수 있는 최대 중요도가 dp[i][j]가 된다.
dp 배열을 채운 후, dp[K][N]을 출력해주면 된다.
아래는 코드.
#include <iostream>
#include <utility>
#include <algorithm>
using namespace std;
int main()
{
cin.tie(NULL);
ios::sync_with_stdio(false);
int N, K;
cin >> N>>K;
pair<int, int>* subjects = new pair<int, int>[K];
long long** dp = new long long*[K+1];
for (int i = 0; i < K+1; i++)
{
dp[i] = new long long[N + 1];
for (int j = 0; j < N + 1; j++)
{
dp[i][j] = 0;
}
}
for (int i = 0; i < K; i++)
{
cin >> subjects[i].second >> subjects[i].first;
}
sort(subjects, subjects + K);
for (int i = 0; i < K; i++)
{
int studyTime = subjects[i].first;
int importance = subjects[i].second;
for (int j = 0; j < N+1; j++)
{
if (j < studyTime)
{
dp[i + 1][j] = dp[i][j];
}
else
{
dp[i + 1][j] = max(dp[i][j - studyTime] + importance, dp[i][j]);
}
}
}
cout << dp[K][N] << "\n";
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
[백준 2747] 피보나치 수 (C++) (0) | 2024.07.24 |
---|---|
[백준 1347] 미로 만들기 (C++) (0) | 2024.07.23 |
[백준 29717] 슬라임 잡고 레벨 업! (C++) (0) | 2024.07.21 |
[백준 11048] 이동하기 (C++) (0) | 2024.07.20 |
[백준 3986] 좋은 단어 (C++) (0) | 2024.07.19 |