-
내려가기 - 2096Algorithm/BOJ 2020. 3. 14. 03:351234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465//2096 - 내려가기#include <iostream>using namespace std;#define INF 100000000int N;int arr[100000][3];int cache[2][3];int cache2[2][3];void init(){cin >> N;for (int i = 0; i < N; ++i)for (int j = 0; j < 3; ++j)cin >> arr[i][j];}int dp(int x, int y){if (y == -1 || y == 3)return -1;if (x == N - 1)return arr[x][y];return cache[x % 2][y];}int dp2(int x, int y){if (y == -1 || y == 3)return INF;if (x == N - 1)return arr[x][y];return cache2[x % 2][y];}int main(){ios_base::sync_with_stdio(0); cin.tie(0);init();for(int i = 0; i<3; ++i)cache[0][i] = cache2[0][i] = arr[0][i];for (int i = N - 2; i >= 0; --i){for (int j = 0; j < 3; ++j)cache[i % 2][j] = -1, cache2[i % 2][j] = INF;for (int j = 0; j < 3; ++j){for (int k = -1; k <= 1; ++k)cache[i % 2][j] = max(cache[i % 2][j], dp(i + 1, j + k)),cache2[i % 2][j] = min(cache2[i % 2][j], dp2(i + 1, j + k));cache[i % 2][j] += arr[i][j];cache2[i % 2][j] += arr[i][j];}}int ans = 0, ans2 = INF;for (int i = 0; i < 3; ++i)ans = max(ans, cache[0][i]), ans2 = min(ans2, cache2[0][i]);cout << ans << " " << ans2;}
cs 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
내려가기
Cmin(x, y) : (x, y)까지 진행한 것중 가장 작은 값
Cmax(x, y) : (x, y)까지 진행한 것중 가장 큰 값
Cmin(x, y) = (-1 <= k <= 1)min{Cmin(x+1, y+k)} + arr[x][y]
Cmax(x, y) = (-1 <= k <= 1)max{Cmax(x+1, y+k)} + arr[x][y]
처음에는 위의 점화식으로 재귀함수를 만들어 해결하려 했습니다. 하지만 기본적으로 소모되는 메모리에 cache를 위한 4*100000*3 만큼의 바이트로인해 메모리 초과가 발생하였습니다.
더 좋은 점화식을 생각해 내지 못했고, 또 제가 알고있는 점화식에선 현재 단계를 생성하기 위해 오직 이전단계만을 필요로 하기에, 반복문을 이용한 dp에 슬라이딩 윈도 기법을 이용하여 메모리 사용량을 줄여주었습니다.
(재귀함수 dp는 슬라이딩윈도 기법을 사용할 수 없습니다.)

'Algorithm > BOJ' 카테고리의 다른 글
구간 합 구하기 - 2042 (0) 2020.03.15 영우의 기숙사 청소 - 15806 (0) 2020.03.15 최솟값 - 10868 (0) 2020.03.13 최솟값과 최댓값 - 2357 (0) 2020.03.13 퀘스트 중인 모험가 - 15816 (0) 2020.03.13