Doby's Lab

백준 11909번: 배열 탈출 (C++) 본문

PS/BOJ

백준 11909번: 배열 탈출 (C++)

도비(Doby) 2023. 6. 20. 21:26

https://www.acmicpc.net/problem/11909

 

11909번: 배열 탈출

상수는 2차원 배열 A[1..n][1..n] (n≥2, n은 자연수)을 가지고 있습니다. 이 배열의 각 원소는 1 이상 222 이하의 정수입니다. 배열을 가지고 놀던 상수를 본 승현이는, 질투심이 불타올라 상수를 A[1][1]

www.acmicpc.net


Level: Gold V

Solved By: DP

 

처음에는 Dijkstra로 풀려고 했었습니다. pair<pair<int, int>, int> 같은 복잡한 자료형을 만들어서 구현했는데 메모리 초과로 다른 키워드를 생각해내야 했습니다. DP 태그가 달려있어서 DP로도 구현할 수 있겠다 싶었습니다.

 

제가 생각한 아이디어와 관계식은 아래와 같습니다

\(cache\)는 해당 원소로 갔을 때, 최단 경로 값을 저장할 2차원 배열이며, \(q\)는 원소 위치 별로 상수 값을 저장해 놓은 2차원 배열입니다.

$$ \begin{align}
cache(i, j) = min(cost_{1} + cache(i-1, j),\ cost_{2}+cache(i, j-1))\\ \\

cost_{1} = \left\{
\begin{array}{lr}
0 & : q(i, j) - q(i-1, j) <0\\
q(i,j) - q(i-1, j)+1 & : q(i, j) - q(i-1, j) \geq0
\end{array}
\right.\\ \\

cost_{2} = \left\{
\begin{array}{lr}
0 & : q(i, j) - q(i, j-1) <0\\
q(i,j) - q(i, j-1)+1 & : q(i, j) - q(i, j-1) \geq0
\end{array}
\right.

\end{align} $$

 

다만, 이러한 관계식이 적용되기 위해서는 당연히 고려되는 이전 원소들이 전부 다 업데이트가 되어있어야 합니다. (Bottom-Up)

그래서 이를 해결하기 위해 \(k=i+j\ (1 \leq k \leq 2 * N,\ 1\leq i \leq k)\)이와 같은 식을 만들어서 (1, 3), (2, 2), (3, 1) -> (1, 4), (2, 3)... 이런 순서대로 DP를 할 수 있도록 코드를 만들어줬습니다.

#include <iostream>
#define MAX 2223
#define INF 1e9
using namespace std;

int N;

int q[MAX][MAX];
int cache[MAX][MAX];

int main(){
    cin >> N;
    for(int i = 1; i <= N; i++){
        for(int j = 1; j<= N; j++){
            cin >> q[i][j];
        }
    }
    
    for(int k = 3; k <= N + N; k++){
        for(int i = 1; i <= k; i++){
            int j = k - i;
            if(i > N || j > N) continue;
            
            int up = INF, left = INF;
            if(j - 1 > 0){
                int cost = (q[i][j-1] - q[i][j] > 0 ? 0 :q[i][j] - q[i][j-1] + 1);
                left = min(left, cost + cache[i][j-1]);
            }
            if(i - 1 > 0){
                int cost = (q[i-1][j] - q[i][j] > 0 ? 0 :q[i][j] - q[i-1][j] + 1);
                up = min(up, cost + cache[i-1][j]);
            }
            cache[i][j] = min(up, left);
        }
    }
    cout << cache[N][N];
    return 0;
}

728x90