Algorithm/알고리즘 백준 풀이
[백준] #1932 정수삼각형 - (DP)
i009727
2020. 3. 2. 15:28
(문제
https://www.acmicpc.net/problem/1932
1932번: 정수 삼각형
문제 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 위 그림은 크기가 5인 정수 삼각형의 한 모습이다. 맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다. 삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는
www.acmicpc.net
목표
정수로 이루어진 삼각형이 주어질때 맨위에서 대각선으로만 내려가면서 수를 선택하여 최대값을 구하는문제
풀이
DP로 풀이
점화식: dp[i][j] = max(dp[i][j], dp[i][j-1]) + dp[i][j];
즉, 단계마다 이전 단계 왼쪽위, 오른쪽위 수를 확인하여 큰값에 현재 자신의 값을 더한값으로 dp배열을 재구성한다.
코드
1. 재귀를 이용하여 구현
: 2020.03.17 다시 풀다보니까 재귀로 풀려서 추가함
////재귀를 이용하여 구현
#include <iostream>
#include <cstring>
#define MAX 501
using namespace std;
int N;
int arr[MAX][MAX];
//dp[i][j] = i행 j열에 해당하는 최대값을 저장
int dp[MAX][MAX];
int func(int row, int col) {
// cout << "Func call: " << row << ", " << col << '\n';
if (row == -1)
return 0;
int &ref = dp[row][col];
if (ref != -1)
return ref;
//맨 왼쪽 열인경우: 선택지 1개
if (col == 0)
ref = max(ref, func(row-1, col) + arr[row][col]);
//맨 오른쪽 열인경우: 선택지 1개
else if (col == row)
ref = max(ref, func(row-1, col-1) + arr[row][col]);
//중간에 위치한 열인경우: 선택지 2개
else {
ref = max(ref, func(row-1, col-1) + arr[row][col]);
ref = max(ref, func(row-1, col) + arr[row][col]);
}
return ref;
}
int main() {
cin >> N;
for (int i=0; i<N; ++i) {
for (int j=0; j<=i; ++j) {
cin >> arr[i][j];
}
}
memset(dp, -1, sizeof(dp));
int result = -1;
//맨 아래 행에서 최대값을 찾아 출력
for (int i=0; i<N; ++i) {
result = max(result, func(N-1, i));
}
cout << result;
cout << endl;
for (int i=0; i<N; ++i) {
for (int j=0; j<=i; ++j) {
cout << dp[i][j] << " ";
}
cout << '\n';
}
}
2. 반복을 이용하여 구현
#include <iostream>
#include <vector>
#define MAX_TRI 501
using namespace std;
int H;
int dp[MAX_TRI][MAX_TRI];
int func1() {
int res = 0;
for (int i=1; i<=H; ++i) {
for (int j=1; j<=i; ++j) {
dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + dp[i][j];
if (res < dp[i][j])
res = dp[i][j];
}
}
return res;
}
int main() {
cin >> H;
for (int i=1; i<=H; ++i) {
for (int j=1; j<=i; ++j) {
cin >> dp[i][j];
}
}
cout << func1();
}