#문제

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

 

1520번: 내리막 길

첫째 줄에는 지도의 세로의 크기 M과 가로의 크기 N이 빈칸을 사이에 두고 주어진다. 이어 다음 M개 줄에 걸쳐 한 줄에 N개씩 위에서부터 차례로 각 지점의 높이가 빈 칸을 사이에 두고 주어진다. M과 N은 각각 500이하의 자연수이고, 각 지점의 높이는 10000이하의 자연수이다.

www.acmicpc.net

 

#작성 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;
 
int m, n;
// map과 dp배열 (1,1) ~ (m,n) 사용 
int map[501][501];
int dp[501][501];
int d[4][2= {{-1,0}, {1,0}, {0,-1}, {0,1}};
 
bool isIn(int x, int y){
    return x>=1&&x<=m&&y>=1&&y<=n;
}
 
int downhill(int x, int y){
    if( dp[x][y]!=-1 ) return dp[x][y];    // 이미 계산한 적 있다면 그 값 리턴 
    if!isIn(x, y)) return 0;            // 범위를 벗어났다면 그 곳까지 가는 경우의 수는 0이다 
    if( x==1 && y==1 ) return 1;        //(1,1)에서 출발해서 (1,1)에 도착하는 경우의 수 : 1 
    
    dp[x][y] = 0;        // dp를 새로 계산할 때는 0으로 초기화하고 더해야한다. 
     
    for(int di=0; di<4; di++){
        // (x,y)의 상하좌우 탐색 
        int nextX = x+d[di][0];
        int nextY = y+d[di][1];
        // (x,y)보다 (nextX,nextY)의 높이가 높다면
        // (x,y)까지 가는 경우의 수 += 각 (nextX,nextY)까지 가는 경우의 수 
        if( map[nextX][nextY] > map[x][y] ){
            dp[x][y] += downhill(nextX, nextY);
        }
    }
    // 계산된 (x,y)까지 가는 경우의 수를 리턴한다. 
    return dp[x][y];    
}
int main(){
    cin>>m>>n;
    for(int i=1; i<=m; i++){
        for(int j=1; j<=n; j++){
            cin>>map[i][j];
            dp[i][j]=-1;    // dp배열 -1로 초기화. 
        }
    }
    cout<<downhill(m,n)<<'\n';
    return 0;
}
cs

##

bfs로 할 수 있을까? 하다가 dfs로 시도해보았다.

' (x,y)까지 가는 경우의 수 : (x,y)상하좌우 중에서 그보다 높이가 높은 곳까지 가는 경우의 수의 합 ' 이 부분이 가장 중요한 부분이다.

dp를 이용해서 한번 계산한 경우의 수에 대해서는 그 값을 그대로 불러와서 다시 계산하지 않도록 하였다.

'BOJ' 카테고리의 다른 글

BOJ 4781번 :: 사탕가게  (0) 2020.01.23
BOJ 7579번 :: 앱  (0) 2020.01.23
BOJ 12015번 :: 가장 긴 증가하는 부분 수열 2  (0) 2020.01.06
BOJ 11055번 :: 가장 큰 증가 부분 수열  (0) 2020.01.06
BOJ 11049번 :: 행렬 곱셈 순서  (0) 2020.01.06

+ Recent posts