일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
- boj 1464
- 최장증가수열
- disjoint set
- bfs
- 백준 1464
- 결정문제
- 이분 탐색
- 재귀
- 브루트포스
- 최장길이바이토닉수열
- Lis
- 서로소 집합
- 2493 백준
- 그래프 이론
- 1939백준
- 깊이 우선 탐색
- 그래프탐색
- 구현
- 백준 뒤집기 3
- 뒤집기 3
- 분할정복
- 이분탐색
- 패스트캠퍼스
- 그래프 탐색
- 그래프이론
- union find
- 결정 문제
- 비트마스킹
- parametric search
- DP
- Today
- Total
알고리즘 문제풀이
[BOJ] 14728 번 - 벼락치기 본문
백준 14728번 - 벼락치기
시간제한 | 메모리 제한 | 제출 | 정답 | 맞은 사람 | 정답 비율 |
---|---|---|---|---|---|
2 초 | 256 MB | 2088 | 874 | 673 | 41.723% |
문제
ChAOS(Chung-ang Algorithm Organization and Study) 회장이 되어 일이 많아진 준석이는 시험기간에도 일 때문에 공부를 하지 못하다가 시험 전 날이 되어버리고 말았다. 다행히도 친절하신 교수님께서 아래와 같은 힌트를 시험 전에 공지해 주셨다. 내용은 아래와 같다.
- 여러 단원을 융합한 문제는 출제하지 않는다.
- 한 단원에 한 문제를 출제한다. 단, 그 단원에 모든 내용을 알고 있어야 풀 수 있는 문제를 낼 것이다.
이런 두가지 힌트와 함께 각 단원 별 배점을 적어 놓으셨다. 어떤 단원의 문제를 맞추기 위해서는 그 단원의 예상 공부 시간만큼, 혹은 그보다 더 많이 공부하면 맞출 수 있다고 가정하자. 이때, ChAOS 회장 일로 인해 힘든 준석이를 위하여 남은 시간 동안 공부해서 얻을 수 있는 최대 점수를 구하는 프로그램을 만들어 주도록 하자.
입력
첫째 줄에는 이번 시험의 단원 개수 N(1 ≤ N ≤ 100)과 시험까지 공부 할 수 있는 총 시간 T(1 ≤ T ≤ 10000)가 공백을 사이에 두고 주어진다.
둘째 줄부터 N 줄에 걸쳐서 각 단원 별 예상 공부 시간 K(1 ≤ K ≤ 1000)와 그 단원 문제의 배점 S(1 ≤ S ≤ 1000)가 공백을 사이에 두고 주어진다.
출력
첫째 줄에 준석이가 얻을 수 있는 최대 점수를 출력한다.
예제 입력 1
3 310
50 40
100 70
200 150
예제 출력 1
220
출처
www.acmicpc.net/problem/14728
14728번: 벼락치기
ChAOS(Chung-ang Algorithm Organization and Study) 회장이 되어 일이 많아진 준석이는 시험기간에도 일 때문에 공부를 하지 못하다가 시험 전 날이 되어버리고 말았다. 다행히도 친절하신 교수님께서 아래와
www.acmicpc.net
알고리즘 분류
- 다이나믹 프로그래밍
- 배낭 문제
접근 방법
위 문제를 해결하기 위해 가장 쉽게 떠올릴 수 있는 방법으로는 가능한 모든 경우를 다 따지는 것이다.
for문으로 i번째 task를 처리할지?/말지? 를 결정하는 2가지 방법이 문제의 개수인 N개가 존재하므로, 시간 복잡도는 $O(2^n)$ 이 될 것이다.
이것을 dynamic programming 을 통해 $O(N^2)$으로 줄일 수 있다.
그것이 바로 유명한 knapsack problem 이다.
이 문제의 유형은 쪼갤 수 없는 0/1 knapsack problem이다.
우리가 찾고자 하는 답이 특정 조건을 만족하는 최적해라면 memoization을 통해 문제를 해결할 수 있다.
위 문제에서 DP를 다음과 같이 정의해보자.
DP[i][j] = i번째 문제까지 확인했을 때, j시간 내에 얻을 수 있는 최대 점수
2차원 배열로 구현한 이유는 0/1 knapsack problem의 특성 상 모든 경우를 확인하지 않고, 각 단계별로 최적이 될 수 있는 후보해들만 고려해주는 것이기 때문이다.
DP[i][j]의 최적해가 될 수 있는 최적해는 2가지 경우 중 하나 이다.
-
이전 작업(i-1) 까지만 고려했을 때, j시간 내에 얻을 수 있는 최대 점수
-
i번째 문제를 풀 수 있는 경우, i-1까지 고려했던 문제들 중 j시간내에 얻을 수 있었던 최대 점수 + 현재 문제의 점수
위의 식을 다음과 같은 점화식으로 표현할 수 있다.
소스 코드
#include <bits/stdc++.h>
using namespace std;
int N, T;
vector<int> req_time, score;
int main(void){
ios_base::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin >> N >> T;
req_time.resize(N), score.resize(N);
for(int i=0; i<N; i++){
cin >> req_time[i] >> score[i];
}
/// dp[i][j] : i번째 작업까지 확인했을 때, j시간 내에 얻을 수 있는 최대 점수
int dp[101][100001] = {0,};
for(int i=req_time[0]; i<=100000; i++)
dp[0][i] = score[0];
for(int i=1; i<N; i++){
int t = req_time[i], s = score[i];
for(int j=1; j<=100000; j++){
if( j - t >= 0 ){
dp[i][j] = max(dp[i-1][j-t] + s, dp[i][j]);
}
dp[i][j] = max(dp[i][j], dp[i-1][j]);
}
}
cout << dp[N-1][T];
return 0;
}
'자료구조 + 알고리즘 > [BOJ]' 카테고리의 다른 글
[BOJ] 1464 번 - 뒤집기 3 (0) | 2021.01.25 |
---|---|
[BOJ] 2623번 - 음악프로그램 (0) | 2021.01.24 |
[BOJ] 2098 - 외판원 순회 (0) | 2021.01.17 |
[BOJ] 14891 번 - 톱니바퀴 (0) | 2021.01.15 |
[BOJ] 13460번 - 구슬 탈출 2 (0) | 2021.01.07 |