λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

πŸ“ μ•Œκ³ λ¦¬μ¦˜/BOJ

[C++/BOJ] 1890 : 점프 (DP)

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

 

문제

N×N κ²Œμž„νŒμ— μˆ˜κ°€ μ ν˜€μ Έ μžˆλ‹€. 이 κ²Œμž„μ˜ λͺ©ν‘œλŠ” κ°€μž₯ μ™Όμͺ½ μœ„ μΉΈμ—μ„œ κ°€μž₯ 였λ₯Έμͺ½ μ•„λž˜ 칸으둜 κ·œμΉ™μ— 맞게 점프λ₯Ό ν•΄μ„œ κ°€λŠ” 것이닀.

각 칸에 μ ν˜€μžˆλŠ” μˆ˜λŠ” ν˜„μž¬ μΉΈμ—μ„œ 갈 수 μžˆλŠ” 거리λ₯Ό μ˜λ―Έν•œλ‹€. λ°˜λ“œμ‹œ 였λ₯Έμͺ½μ΄λ‚˜ μ•„λž˜μͺ½μœΌλ‘œλ§Œ 이동해야 ν•œλ‹€. 0은 더 이상 진행을 λ§‰λŠ” 쒅착점이며, 항상 ν˜„μž¬ 칸에 μ ν˜€μžˆλŠ” 수만큼 였λ₯Έμͺ½μ΄λ‚˜ μ•„λž˜λ‘œ κ°€μ•Ό ν•œλ‹€. ν•œ 번 점프λ₯Ό ν•  λ•Œ, λ°©ν–₯을 λ°”κΎΈλ©΄ μ•ˆ λœλ‹€. 즉, ν•œ μΉΈμ—μ„œ 였λ₯Έμͺ½μœΌλ‘œ 점프λ₯Ό ν•˜κ±°λ‚˜, μ•„λž˜λ‘œ 점프λ₯Ό ν•˜λŠ” 두 경우만 μ‘΄μž¬ν•œλ‹€.

κ°€μž₯ μ™Όμͺ½ μœ„ μΉΈμ—μ„œ κ°€μž₯ 였λ₯Έμͺ½ μ•„λž˜ 칸으둜 κ·œμΉ™μ— 맞게 이동할 수 μžˆλŠ” 경둜의 개수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 κ²Œμž„ 판의 크기 N (4 ≤ N ≤ 100)이 주어진닀. κ·Έ λ‹€μŒ N개 μ€„μ—λŠ” 각 칸에 μ ν˜€μ Έ μžˆλŠ” μˆ˜κ°€ Nκ°œμ”© 주어진닀. 칸에 μ ν˜€μžˆλŠ” μˆ˜λŠ” 0보닀 ν¬κ±°λ‚˜ κ°™κ³ , 9보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜μ΄λ©°, κ°€μž₯ 였λ₯Έμͺ½ μ•„λž˜ μΉΈμ—λŠ” 항상 0이 주어진닀.

좜λ ₯

κ°€μž₯ μ™Όμͺ½ μœ„ μΉΈμ—μ„œ κ°€μž₯ 였λ₯Έμͺ½ μ•„λž˜ 칸으둜 문제의 κ·œμΉ™μ— 맞게 갈 수 μžˆλŠ” 경둜의 개수λ₯Ό 좜λ ₯ν•œλ‹€. κ²½λ‘œμ˜ κ°œμˆ˜λŠ” 2^63-1보닀 μž‘κ±°λ‚˜ κ°™λ‹€.


싀버1. dp μ€‘μ—λŠ” μ‰¬μš΄νŽΈμ΄λ‹€

 

μœ μ˜μ‚¬ν•­!

λ‹΅μ˜ λ²”μœ„κ°€ 2^63-1보닀 μž‘κ±°λ‚˜ κ°™μœΌλ―€λ‘œ int ν˜•μœΌλ‘œ ν’€λ©΄ ν‹€λ¦°λ‹€ γ… γ… 

int의 λ²”μœ„λŠ” μ΅œλŒ€ 2^31-1 μ΄λ―€λ‘œ, long long ν˜•μœΌλ‘œ κ³ μ³μ£Όμ—ˆλ”λ‹ˆ λ§žμ•˜μŒ

 

main ideaλŠ” 경우의 수λ₯Ό dp둜 λˆ„μ μ‹œν‚€λŠ” 것이닀.

 

μ²˜μŒμ— μ•„μ΄λ””μ–΄λŠ” λ– μ˜¬λ¦¬κΈ° μ‰¬μ› λŠ”λ°, κ΅¬ν˜„ ν›„ 닡이 ν‹€λ¦¬κ²Œ λ‚˜μ™€μ„œ μ–΄λ””κ°€ ν‹€λ ΈλŠ”μ§€ μ°Ύμ•„λ³΄λ‹ˆ

λ§ˆμ§€λ§‰μ— map[i][j]κ°€ 0μΌλ•Œλ„ map[i][j]에 본인의 κ°’이 계속 λˆ„μ λ˜μ–΄μ„œ ν‹€λ¦° κ²ƒμ΄μ—ˆλ‹€

κ·Έλž˜μ„œ map[i][j] == 0μΌλ•Œ continue;ꡬ문을 λ„£μ–΄μ€¬λ”λ‹ˆ 닡이 μ˜¬λ°”λ₯΄κ²Œ 좜λ ₯λ˜μ—ˆλ‹€.

 

 

 

λ‚˜μ˜ 풀이

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

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    int n;
    int map[101][101]={0};
    long long cnt[101][101] = {0};
    cin >> n;
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < n; ++j){
            cin >> map[i][j];
        }
    }
    cnt[0][0] = 1;
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < n; ++j){
            if(map[i][j]==0) continue; // λ§ˆμ§€λ§‰μ— 계속 값이 λˆ„μ λ˜λŠ”κ±Έ λ§‰κΈ°μœ„ν•΄ μ˜ˆμ™Έμ²˜λ¦¬ ν•„μš”
            int go = map[i][j];
            if(i + go < n) cnt[i + go][j] += cnt[i][j];
            if(j + go < n) cnt[i][j + go] += cnt[i][j];
        }
    }

    cout << cnt[n-1][n-1];
    return 0;
}