Computer Science
탄탄한 기반 실력을 위한
전공과 이론 지식 모음
Today I Learned!
배웠으면 기록을 해야지
TIL 사진
Flutter 사진
Flutter로 모바일까지
거꾸로캠퍼스 코딩랩 Flutter 앱개발 강사
스파르타코딩클럽 즉문즉답 튜터
카카오테크캠퍼스 3기 학습코치
프로필 사진
박성민
임베디드 세계에
발을 들인 박치기 공룡
임베디드 사진
EMBEDDED SYSTEM
임베디드 SW와 HW, 이론부터 실전까지
ALGORITHM
알고리즘 해결 전략 기록
🎓
중앙대학교 소프트웨어학부
텔레칩스 차량용 임베디드 스쿨 3기
애플 개발자 아카데미 1기
깃허브 사진
GitHub
프로젝트 모아보기
Instagram
인스타그램 사진

Develop/알고리즘

[백준] 11048 - 이동하기

sm_amoled 2021. 12. 25. 13:15

문제링크

https://www.acmicpc.net/problem/11048

문제

준규는 N×M 크기의 미로에 갇혀있다. 미로는 1×1크기의 방으로 나누어져 있고, 각 방에는 사탕이 놓여져 있다. 미로의 가장 왼쪽 윗 방은 (1, 1)이고, 가장 오른쪽 아랫 방은 (N, M)이다.

준규는 현재 (1, 1)에 있고, (N, M)으로 이동하려고 한다. 준규가 (r, c)에 있으면, (r+1, c), (r, c+1), (r+1, c+1)로 이동할 수 있고, 각 방을 방문할 때마다 방에 놓여져있는 사탕을 모두 가져갈 수 있다. 또, 미로 밖으로 나갈 수는 없다.

준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수의 최댓값을 구하시오.

입력

첫째 줄에 미로의 크기 N, M이 주어진다. (1 ≤ N, M ≤ 1,000)

둘째 줄부터 N개 줄에는 총 M개의 숫자가 주어지며, r번째 줄의 c번째 수는 (r, c)에 놓여져 있는 사탕의 개수이다. 사탕의 개수는 0보다 크거나 같고, 100보다 작거나 같다.

출력

첫째 줄에 준규가 (N, M)으로 이동할 때, 가져올 수 있는 사탕 개수를 출력한다.

조건

  • 시간 제한 : 1s
  • 메모리 제한 : 256MB

해설

(r, c)에 대해서는 (r-1, c), (r, c-1), (r-1, c-1)에서 접근할 수 있는데, 최대한 많은 방을 방문하는 것이 이득이므로 (r-1, c), (r, c-1)에서 접근하는 경우만 생각해주면 된다.

2차원 벡터를 만들어서, (1, 1) 에서 (M, N) 까지 가는 길에 있는 사탕의 합을 각 방에 대응하는 dp에 저장하면서 구하면 된다.

풀이

(r-1, c-1)에 접근을 하기위해 왼쪽, 위쪽 면을 0으로 채워야 하기에, M, N을 입력받으면 M+1, N+1의 크기를 갖는 2차원 벡터를 만든다.

int M, N;
cin >> M >> N;

vector<vector<int>> dp(M+1, vector<int> (N+1, 0));

(i, j) 에 대해서는 dp(i-1, j), dp(i, j-1) 중 큰 값에 (i, j)에 있는 사탕 개수를 합하여 dp(i, j)의 값을 구할 수 있다. 이를 코드로 구현하면 아래처럼 작성할 수 있다.

int input;
for(int i = 1; i <= M; i++) {
    for(int j = 1; j <= N; j++) {
        cin >> input;   
        dp[i][j] += (input + ((dp[i-1][j] > dp[i][j-1])? dp[i-1][j] : dp[i][j]; 
    }
}

위 반복문을 종료하고 나면, dp[M][N]에 원하는 결과가 담겨있다.

cout << dp[M][N];

코멘트

이까지는 할 만 하지 ㅎㅎ


코드

#include <iostream>
#include <vector>

using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    
    int M, N;
    cin >> M >> N;
    
    vector<vector<int>> dp(M+1, vector<int> (N+1, 0));
    
    int input;
    for(int i = 1; i <= M; i++) {
        for(int j = 1; j <= N; j++) {
            cin >> input;   
            dp[i][j] += (input + ((dp[i-1][j] > dp[i][j-1])? dp[i-1][j] : dp[i][j-1]));  
        }
    }
    
    cout << dp[M][N];
    return 0;
}
320x100

'Develop > 알고리즘' 카테고리의 다른 글

[백준] 2225 - 합분해  (0) 2021.12.25
[백준] 1904 - 01타일  (0) 2021.12.25
[백준] 11054 - 가장 긴 증가하는 바이토닉 부분 수열  (0) 2021.12.25
[백준] 17298 - 오큰수  (0) 2021.12.25
[백준] 2293 - 동전 1  (0) 2021.12.25