백준 1932번. 정수 삼각형

연성·2020년 9월 27일
0

코딩테스트

목록 보기
23/261

0. 문제 링크

백준 1932번. 정수 삼각형

프로그래머스. 정수 삼각형

1. 문제

	7
      3   8
    8   1   0
  2   7   4   4
4   5   2   6   5

위 그림은 크기가 5인 정수 삼각형의 한 모습이다.

맨 위층 7부터 시작해서 아래에 있는 수 중 하나를 선택하여 아래층으로 내려올 때, 이제까지 선택된 수의 합이 최대가 되는 경로를 구하는 프로그램을 작성하라. 아래층에 있는 수는 현재 층에서 선택된 수의 대각선 왼쪽 또는 대각선 오른쪽에 있는 것 중에서만 선택할 수 있다.

삼각형의 크기는 1 이상 500 이하이다. 삼각형을 이루고 있는 각 수는 모두 정수이며, 범위는 0 이상 9999 이하이다.

2. 입력

  • 첫째 줄에 삼각형의 크기 n(1 ≤ n ≤ 500)이 주어지고, 둘째 줄부터 n+1번째 줄까지 정수 삼각형이 주어진다.

3. 출력

  • 첫째 줄에 합이 최대가 되는 경로에 있는 수의 합을 출력한다.

4. 풀이

  • dp 문제
  • 그려서 하나하나 더 하다가 알았다.
  • 특정 노드(인지 모르겠지만 그냥 노드라고 하자...)에 연결된 노드는 2개다. 그 두 개중 더 큰 수를 고르면 된다. 어차피 자기 자신은 똑같이 더하니까
  • (i,j)와 연관된 노드는 (i-1, j)(i-1, j-1)이다.
  • 근데 첫번째 노드는 (i-1, j-1)가 없고 마지막 노드는 (i-1, j)가 없다.
  • 그래서 각각을 if와 else if로 처리하고 남은 걸 else로 처리하려고 했다.
  • 근데 나는 2차원 배열을 쓸 거고 삼각형이라서 나머지 반은 비어있다.(정확히는 0으로 초기화했다.) 그래서 마지막 노드의 (i-1, j) 0이고 max에서 알아서 걸러질 거라서 if 처리할 필요가 없어졌다.
  • 그리고 첫번째 노드는 이중 루프의 안쪽을 0부터 시작하지 않고 1부터 시작하고 0은 루프 시작하기 전에 처리해줬다.
  • ifelse if 그리고 else를 써줘야 했던게 다 사라졌다.
  • 이럴 때 가장 행복하다. 뿌듯하다.
  • 마지막 줄까지 각 경로의 최댓값이 저장되어 있고 이 중 최댓값이 전체 경로의 최댓값이다.

5. 처음 코드와 달라진 점

  • 왜 그랬는지는 모르겠는데 arr[i][0]을 써야 하는데 arr[i-1][0]을 썼다...ㅎ
  • 그거 말고는 없어다.
  • 배열 입력 받을 때 변수 선언하기 싫어서 cin 안쓰고 scanf를 쓰는데 VS는 scanf 쓰면 쓰지말라고 뭐라하고 백준은 scanf_s를 쓰면 틀렸다고 뭐라고 한다... 인생

6. 코드

6-1. 백준

#include <iostream>
#include <algorithm>
using namespace std;

int arr[500][500] = { 0 }, dp[500][500] = { 0 };

int main() {
	int n;
	cin >> n;

	for (int i = 0; i < n; i++){
		for (int j = 0; j <= i; j++) {
			scanf_s("%d", &arr[i][j]);
		}
	}

	dp[0][0] = arr[0][0];

	for (int i = 1; i < n; i++) {
		dp[i][0] = dp[i - 1][0] + arr[i][0];
		for (int j = 1; j <= i; j++) {
			dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - 1]) + arr[i][j];
		}
	}

	int maxValue = 0;

	for (int i = 0; i < n; i++) {
		maxValue = max(dp[n - 1][i], maxValue);
	}

	cout << maxValue << endl;
}

6-2. 프로그래머스 코드

#include <vector>
#include <algorithm>

using namespace std;
int dp[500][500];

int solution(vector<vector<int>> triangle) {
    int answer = 0;
    
    dp[0][0] = triangle[0][0];
    
    for(int i=1; i<triangle.size(); i++){
        dp[i][0] = dp[i-1][0] + triangle[i][0];
        for(int j=1; j<triangle[i].size(); j++){
            dp[i][j] = max(dp[i-1][j-1], dp[i-1][j]) + triangle[i][j];
        }
    }
    
    int last_col = triangle.size() -1;
    for(int i=0; i<triangle[last_col].size(); i++){
        answer = max(answer, dp[last_col][i]);
    }
    return answer;
}

0개의 댓글