seukseok의 개인 블로그

BOJ 풀이 노트: DP와 그래프 도달성 기본기 점검

· tech

BOJ 1932와 11403을 대상으로, 삼각형 DP와 경로 존재 행렬 갱신(Floyd-Warshall)을 구현 실수 포인트 중심으로 정리한 풀이 노트.

오늘은 서로 결이 다른 2문제를 묶어서 풀었다.

1932는 전형적인 누적 최적화 DP, 11403은 정점 간 도달 가능성을 행렬로 갱신하는 그래프 문제다. 둘 다 구현은 짧지만, 인덱스 처리나 갱신 순서를 잘못 잡으면 틀리기 쉬운 유형이다.

1) BOJ 1932 - 정수 삼각형

문제 핵심 요약

삼각형 형태로 주어진 수들에서, 맨 위에서 시작해 바로 아래층의 인접한 칸으로만 내려가며 얻을 수 있는 최대 합을 구하는 문제다.

접근 아이디어(왜 이 방법인지)

각 칸 (i, j)에 도달하는 최대 합은 바로 윗줄의 두 후보 중 큰 값에서 내려오는 방식으로 결정된다.

즉, 부분 문제 최적값을 누적하면 전체 최적해가 되는 전형적인 bottom-up DP다.

시간/공간 복잡도

실수하기 쉬운 포인트

C++ 코드 설명(핵심 라인)

if (j == 1) {
    dp[i][j] = dp[i - 1][j] + triangle[i][j];
} else if (j == i) {
    dp[i][j] = dp[i - 1][j - 1] + triangle[i][j];
} else {
    dp[i][j] = max(dp[i - 1][j - 1], dp[i - 1][j]) + triangle[i][j];
}

경계와 내부를 분리해 전이식을 명확히 처리했다. 이 분기만 정확하면 구현 난이도는 크게 떨어진다.

for (int j = 1; j <= n; ++j) {
    answer = max(answer, dp[n][j]);
}

마지막 줄 어느 칸에서 끝나도 되므로, 마지막 행의 최대값을 최종 답으로 취한다.

다른 풀이 가능성


2) BOJ 11403 - 경로 찾기

문제 핵심 요약

주어진 방향 그래프에서 모든 정점 쌍 (i, j)에 대해, i에서 j로 가는 경로가 존재하는지(1/0) 출력하는 문제다.

접근 아이디어(왜 이 방법인지)

도달 가능 행렬 reachable[i][j]를 두고, 중간 정점 k를 허용하면서 갱신한다.

i -> kk -> j가 가능하면 i -> j도 가능하므로, reachable[i][j] = reachable[i][j] || (reachable[i][k] && reachable[k][j])

이는 Floyd-Warshall의 최단거리 버전이 아니라, 도달성(Transitive Closure) 버전이다. 정점 수가 작아(N <= 100) O(N^3)이 충분히 통과된다.

시간/공간 복잡도

실수하기 쉬운 포인트

C++ 코드 설명(핵심 라인)

for (int k = 0; k < N; ++k) {
    for (int i = 0; i < N; ++i) {
        if (!reachable[i][k]) continue;
        for (int j = 0; j < N; ++j) {
            if (reachable[k][j]) {
                reachable[i][j] = 1;
            }
        }
    }
}

i -> k가 불가능한 경우를 미리 건너뛰어 불필요한 내부 연산을 줄였다. 핵심은 k를 경유지로 쓰는 삼중 루프 구조다.

다른 풀이 가능성


오늘 정리 포인트는 두 가지다.

이런 기본 패턴을 매일 2문제씩 반복하면, 문제를 처음 봤을 때 “이건 어느 전형으로 떨어지는지”를 빠르게 판단하는 힘이 확실히 좋아진다.