-
반응형
https://www.acmicpc.net/problem/2096
2096번: 내려가기
첫째 줄에 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 N개의 줄에는 숫자가 세 개씩 주어진다. 숫자는 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 중의 하나가 된다.
www.acmicpc.net
-풀이-
DP를 이용하여 문제를 풀었다.
최대와 최소는 min, max만 따로 구별하면 되므로, max를 예로 들어보겠다.
현재까지 첫번째 칸, 두번째칸 , 세번째 칸까지 최고비용을 ma[0],ma[1],ma[2] 에 담았다고 하자.
다음칸으로 내려갈때, 다음칸의 첫번째칸, 두번째칸, 세번째칸의 최대비용은 어떻게 구할까?
이런식으로 존재한다 했을때, a로 갈 수 있는 칸은 1번칸과 2번칸이다. 따라서 다음 1번칸(ma[0]) 을 갱신해주기위해, a`과 b`중 큰 값을 a와 더해서 ma[0]에 넣어주어야한다.
b로 갈 수 있는 칸은, 1번 2번 3번 모두다이다. 2번칸(ma[1]) 을갱신해주기 위해서 a`,b`,c`중 제일 큰값을 구해 b와 더해서 ma[1]에 넣어주어야 한다.
c로 갈 수 있는 칸은 2번,3번칸이다. 따라서 3번칸(ma[2])을 갱신해주기 위해서는 b`과 c`중 큰값을 구해 c와 더해서 ma[2]에 넣어주어야 한다.
이때, 계산하기전에 각 a` , b` , c` 을 뽑아서 임시변수에 저장을 해야한다. 왜냐하면 1번칸을 갱신하면, 2번칸을 계산할때, 갱신된 1번칸의 값이 적용되기때문이다.
마지막 층까지 계산을 마치면, 1번칸 2번칸 3번칸 중 제일 큰 값을 출력해주면 된다.
최솟값은 반대로 해주면 된다.
-시간복잡도-
각층마다 단순계산이므로, O(N)이된다.
-코드-
#include<iostream> #include<algorithm> #include<vector> using namespace std; int mi[3], ma[3]; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int n; cin >> n; for (int i = 0; i < n; i++) { int a, b, c; cin >> a >> b >> c; if (i == 0) { mi[0] = ma[0] = a; mi[1] = ma[1] = b; mi[2] = ma[2] = c; } else { int t1 = mi[0], t2 = mi[1],t3=mi[2]; mi[0] = min(t1 + a, t2 + a); mi[1] = min(t1 + b, min(t2 + b, t3 + b)); mi[2] = min(t2 + c, t3 + c); t1 = ma[0]; t2 = ma[1]; t3 = ma[2]; ma[0] = max(t1 + a, t2 + a); ma[1] = max(t1 + b, max(t2 + b, t3 + b)); ma[2] = max(t2 + c, t3 + c); } } cout << max(ma[0], max(ma[1], ma[2])) << " " << min(mi[0], min(mi[1], mi[2])) << "\n"; return 0; }
반응형'문제풀이 > 백준oj' 카테고리의 다른 글
[백준OJ] 21758번 꿀 따기 (0) 2021.06.08 [백준OJ] 16953번 A->B (0) 2021.06.06 [백준OJ] 7662번 이중 우선순위 큐 (0) 2021.06.02 [백준OJ] 17219번 비밀번호 찾기 (0) 2021.05.29 [백준OJ] 11724번 연결 요소의 개수 (0) 2021.05.28 댓글