프로그래머스/3레벨
[프로그래머스/C++] 정수 삼각형
Koalitsiya
2024. 3. 22. 14:49
프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
- 마지막 열에 거쳐간 숫자의 합의 최댓값들이 있어야함
- 2차원 배열을 만들어서 아래 열로 갈때마다 이 전 2개 칸 중 더 큰 값과 현재 칸의 값을 더한 값을 저장해나가면 됨
- 배열 [i][j]에는 [i-1][j-1], [i-1][j] 중 더 큰 값에 삼각형 [i][j]를 더한 값이 저장됨
- 점화식으로 나타내면 dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j]
- 추가로 왼쪽과 오른쪽 끝에서는 아랫열에 칸이 하나 밖에 없으므로 이에 대한 처리를 해줘야함
- 수행이 끝난 뒤 마지막 열에서 최댓값을 찾아 리턴
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// DP 문제
// i 칸에서 i + 1 칸으로 이동할때 i 칸에서에서 j 번째 숫자는 i + 1 칸의 j 또는 j + 1번째 숫자로 이동 가능
// 거쳐간 숫자의 최댓값을 구하려면 [i][j]까지의 합들이 항상 최댓값이 되어야함
// 즉 [i][j]는 [i-1][j-1]과 [i-1][j] 중 큰 값에 원래 [i][j]에 위치한 값을 더한 값이 됨
// 점화식으로 나타내면 dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j];
// 이게 음수 인덱스가 되면 0으로 인식하게 되어있는건진 잘 모르겠는데 위에 점화식만 반복으로 돌렸는데 문제가 발생하지 않았다
// 그래도 음수 인덱스가 정상은 아니므로 왼쪽 끝과 오른쪽 끝에 대한 처리를 해주자
int dp[500][500];
int solution(vector<vector<int>> triangle) {
int answer = -1;
int height = triangle.size();
dp[0][0] = triangle[0][0];
for(int i = 1; i < height; i++) {
for(int j = 0; j <= i; j++) {
// 왼쪽 끝일 때
if (!j) {
dp[i][j] = dp[i-1][j] + triangle[i][j];
}
// 오른쪽 끝일 때
else if (i == j) {
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 i = 0; i < triangle[height - 1].size(); i++) {
answer = max(answer, dp[height - 1][i]);
}
return answer;
}