일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- 자바시작하기
- 머신러닝공부
- 비지도학습
- c언어 오목
- 머신러닝 강좌
- Gradient Descent
- 지도학습
- python강좌
- C언어
- Python강의
- acmicpc.net
- 자바강좌
- 경사하강법
- 파이썬강의
- JAVA강좌
- 딥러닝
- feature scaling
- 딥러닝공부
- supervised learning
- 인공지능
- 선형회귀
- 자바
- 머신러닝
- 백준 알고리즘
- 파이썬강좌
- java
- unsupervised learning
- 효묘블로그
- 머신러닝 강의
- 비용함수
- Today
- Total
컴공과컴맹효묘의블로그
백준[14728] 벼락치기 본문
https://www.acmicpc.net/problem/14728
14728번: 벼락치기
ChAOS(Chung-ang Algorithm Organization and Study) 회장이 되어 일이 많아진 준석이는 시험기간에도 일 때문에 공부를 하지 못하다가 시험 전 날이 되어버리고 말았다. 다행히도 친절하신 교수님께서 아래와
www.acmicpc.net
.
준석이는 주어진 시간 안에 최대한의 점수를 주는 과목들을 공부해야한다.
각 과목은 cost와 그에대한 가치 value가 있다.
주어진 cost 안에 과목들의 가치의 총 합이 최대가 되게하는 과목집합을 구해야한다.
이 문제를 어떻게 풀어야할까?
쉬운 방법으로는 모든 경우의 수를 구할 수 있다. 하지만 단순 계산해보아도 경우의 수가 2^100이나 된다. 제한시간 안에는 이런 방법으로는 풀 수 없다.
그렇다면 분할정복으로 풀 수있을까?
문제를 조금 단순하게 말해서 "효율"이라는 단어를 사용하겠다.
어떤 과목집합 S와 S의 원소 a가 있다.
주어진 T안에 S를 효율적으로 공부했을때 최대 점수 =
max(S에서 a를 포함해서 공부했을때 최대 점수, S에서 a를 제외하고 공부했을때 최대 점수)
이렇게 분할정복 식을 만들어봤다. 조금더 정리해보자
solve( S, T ) = max( solve( S-a, T-at) + value[a], solve( S-a, T ) )
대충 이런식이다. 이 식은 두개의 매개변수에 대해서 항상 같은 값을 반환하는 함수이기때문에 memozation을 적용할 수 있다.
따라서 이 문제는 분할 정복에서 DP가 되었다.
#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
#define FOR(i, n) for(int i = 0; i < n; i++)
using namespace std;
int N, T;
int arr[101][2];
int cache[101][10001];
int solve(int index, int t) {
if (index == N - 1) {
if (arr[index][0] <= t) {
return arr[index][1];
}
else {
return 0;
}
}
if (cache[index][t] > -1) return cache[index][t];
int a = arr[index][0];
int ret;
if (arr[index][0] <= t) {
ret = solve(index + 1, t - a) + arr[index][1];
}
else ret = 0;
cache[index][t] = max(ret, solve(index + 1, t));
return cache[index][t];
}
int main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
FOR(i, 101) FOR(j, 10001) cache[i][j] = -1;
cin >> N >> T;
for (int i = 0; i < N; i++) {
cin >> arr[i][0] >> arr[i][1];
}
int ans = solve(0, T);
cout << ans;
return 0;
}
'알고리즘 > 백준' 카테고리의 다른 글
백준[2230] 수 고르기 (0) | 2022.07.24 |
---|---|
백준[13913]숨바꼭질 4 (0) | 2022.07.16 |
백준[1406] 에디터 (0) | 2022.05.26 |
백준 알고리즘[1019] 책 페이지 (0) | 2022.03.18 |
백준 알고리즘[9694] 무엇을 아느냐가 아니라 누구를 아느냐가 문제다 (0) | 2020.06.26 |