31번 금광

·2021년 7월 30일
0

이코테_알고리즘

목록 보기
3/23

풀이 전략

1) 처음에는 세로 중에서 가장 큰 친구 뽑아서 오른쪽, 오른쪽 위, 오른쪽 아래로
진행하면서 (+ 예외 처리) 가장 큰값을 추출하려고 했지만,
가장 낮은 값 쪽에 엄청 큰 수 추가하는 방법으로 이러한 방법이 아닌것을
도출했다.

2) 역으로 생각하자.
어쨋든 가장 큰 세로의 인덱스 까지 이동해야 한다.
그 다음에 가장 세로 중 즉 (0,3) / (1,3) / (2,3) 중에서 큰 것을 추출한다.
- 세로 중 3개를 진행 -> for문 하나 추가
- 가로로 이동 for문 ~ m - 1 번 까지
- 타겟으로 잡은 행렬을 기준으로 왼쪽과 왼쪽위, 왼쪽 아래를 바라 보았을때
가장 max값을 타겟으로 잡은 행렬에 저장하는 방식으로 진행하면 된다.
-> 왼쪽 , 왼쪽 아래, 왼쪽 위를 확인하면서 max를 갱신한 for문 1개 추가

3) 예외 처리
: 왼쪽 위, 왼쪽 아래를 바라봤을때, 인덱스 값으 초과하거나, -1값이 될수 잇다.

4) 최대값이어서 max_element하려고 했는데 여기서는 마지막 세로줄쪽의
인덱스만 확인하면 되므로 max(first, second) 를 이용해야 한다.

소스코드

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


int main() {


	int n, m;
	cin >> n >> m;

	vector<vector<int>>v(n, vector<int>(m));

	for (int i = 0; i < n; i++)
	{
		for (int j = 0; j < m; j++)
		{
			cin >> v[i][j];
		}
	}
		
	int left[3] = { -1,-1,-1 };
	int up[3] = { 0,-1,1 };

	for (int second = 1; second < m; second++)
	{
		for (int first = 0; first < n; first++)
		{
			int max = 0;
			//왼쪽, 왼쪽아래, 왼쪽 위 체크하는 부분
			for (int cnt = 0; cnt < 3; cnt++)
			{
				if (first + up[cnt] < 0 || second + left[cnt] < 0 
					|| first + up[cnt] >= n)
					continue;
				int temp = v[first][second] + v[first + up[cnt]][second + left[cnt]];
				
				if (max < temp)
					max = temp;
			}
			v[first][second] = max;
		}
	}
	
	int result = 0;

	for (int i = 0; i < n; i++)
	{
		result = max(result, v[i][m - 1]);
	}

	cout << result;
	return 0;
}

끄적끄적

profile
🔥🔥🔥

0개의 댓글