BOJ 1932. 정수 삼각형
🙇♀️[Silver I] 정수 삼각형 - 1932
성능 요약
메모리: 4796 KB, 시간: 16 ms
분류
다이나믹 프로그래밍
제출 일자
2024년 1월 4일 23:57:10
문제 설명
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5
위 그림은 크기가 5인 정수 삼각형의 한 모습이다.
맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다.
삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는 모두 정수이며, 범위는 0 이상 9999 이하이다.
입력
첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.
출력
첫째 줄에 합이 최대가 되는 경로에 있는 수의 합을 출력한다.
🚀풀이
DP문제로 삼각형의 맨위부터 시작해서 그대로 내려갈건지 오른쪽 아래로 내려갈건지 두가지의 경우가 존재한다.
각 경우에 대해서 최대값을 저장하는 배열을 만들고 계속 내려간다.
int N;
vector<vector<int>> board;
vector<vector<int>> cache;
vector<vector<int>> nextX;
int path(int y, int x)
{
// 기저 사항
if (y == N)
return 0;
// 캐시 확인
int& ret = cache[y][x];
if (ret != -1)
return ret;
{
// 경로 기록
int nextBottom = path(y + 1, x);
int nextBottomRight = path(y + 1, x + 1);
if (nextBottom > nextBottomRight)
nextX[y][x] = x;
else
nextX[y][x] = x + 1;
}
// 적용
//ret = cache[y][x];
//ret += max(ret, cache[y + 1][x]);
//ret += max(ret, cache[y + 1][x + 1]);
return ret = board[y][x] + max(path(y + 1, x), path(y + 1, x + 1));
}
🚀전체 코드
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <vector>
#include <list>
#include <stack>
#include <queue>
using namespace std;
// 오늘의 주제 : TrianglePath
// - (0,0)에서 시작해서 아래 or 우측 아래로 이동 가능
// - 만나는 숫자를 모두 더함
// - 최대가 되는 경로와 더한 값?
// 6
// 1 2
// 3 7 4
// 9 4 1 7
// 2 7 5 9 4
int N;
vector<vector<int>> board;
vector<vector<int>> cache;
vector<vector<int>> nextX;
int path(int y, int x)
{
// 기저 사항
if (y == N)
return 0;
// 캐시 확인
int& ret = cache[y][x];
if (ret != -1)
return ret;
{
// 경로 기록
int nextBottom = path(y + 1, x);
int nextBottomRight = path(y + 1, x + 1);
if (nextBottom > nextBottomRight)
nextX[y][x] = x;
else
nextX[y][x] = x + 1;
}
// 적용
//ret = cache[y][x];
//ret += max(ret, cache[y + 1][x]);
//ret += max(ret, cache[y + 1][x + 1]);
return ret = board[y][x] + max(path(y + 1, x), path(y + 1, x + 1));
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
//freopen("input.txt", "rt", stdin);
cin >> N;
board = vector<vector<int>>(N + 1);
for (int i = 0; i < N; ++i)
{
for (int j = 0; j <= i; ++j)
{
int temp;
cin >> temp;
board[i].push_back(temp);
}
}
//N = board.size();
cache = vector<vector<int>>(N, vector<int>(N, -1));
nextX = vector<vector<int>>(N, vector<int>(N));
int ret = path(0, 0);
cout << ret << '\n';
//// 경로 만들기
//int y = 0;
//int x = 0;
//while (y < N)
//{
// if (y == N - 1)
// {
// cout << board[y][x];
// break;
// }
// cout << board[y][x] << " -> ";
// x = nextX[y][x];
// y++;
//}
}