πŸ•οΈ PS (BOJ)/Dynamic Programming

[BOJ][C++] λ°±μ€€ 1577번: λ„λ‘œμ˜ 개수

선달 2024. 9. 16. 05:10
λ°˜μ‘ν˜•

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

 

문제

세쀀이가 μ‚΄κ³  μžˆλŠ” λ„μ‹œλŠ” μ‹ κΈ°ν•˜κ²Œ 생겼닀. 이 λ„μ‹œλŠ” κ²©μžν˜•νƒœλ‘œ 생겼고, μ§μ‚¬κ°ν˜•μ΄λ‹€. λ„μ‹œμ˜ κ°€λ‘œ ν¬κΈ°λŠ” N이고, μ„Έλ‘œ ν¬κΈ°λŠ” M이닀. 또, μ„Έμ€€μ΄μ˜ 집은 (0, 0)에 있고, μ„Έμ€€μ΄μ˜ ν•™κ΅λŠ” (N, M)에 μžˆλ‹€.

λ”°λΌμ„œ, μ•„λž˜ κ·Έλ¦Όκ³Ό 같이 생겼닀.

μ„Έμ€€μ΄λŠ” μ§‘μ—μ„œ ν•™κ΅λ‘œ κ°€λŠ” 길의 경우의 μˆ˜κ°€ 총 λͺ‡ κ°œκ°€ μžˆλŠ”μ§€ κΆκΈˆν•΄μ§€κΈ° μ‹œμž‘ν–ˆλ‹€.

μ„Έμ€€μ΄λŠ” 항상 μ΅œλ‹¨κ±°λ¦¬λ‘œλ§Œ κ°€κΈ° λ•Œλ¬Έμ—, 항상 λ„λ‘œλ₯Ό μ •ν™•ν•˜κ²Œ N + M개 κ±°μΉœλ‹€. ν•˜μ§€λ§Œ, 졜근 λ“€μ–΄ 이 λ„μ‹œμ˜ λ„λ‘œκ°€ 뢀싀곡사 의혹으둜 곡사쀑인 곳이 μžˆλ‹€. λ„λ‘œκ°€ 곡사 쀑일 λ•ŒλŠ”, 이 λ„λ‘œλ₯Ό μ§€λ‚  수 μ—†λ‹€.

(0, 0)μ—μ„œ (N, M)κΉŒμ§€ κ°€λŠ” μ„œλ‘œ λ‹€λ₯Έ 경둜의 경우의 수λ₯Ό κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 λ„λ‘œμ˜ κ°€λ‘œ 크기 Nκ³Ό μ„Έλ‘œ 크기 M이 μ£Όμ–΄μ§„λ‹€. Nκ³Ό M은 100보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄κ³ , λ‘˜μ§Έ μ€„μ—λŠ” 곡사쀑인 λ„λ‘œμ˜ 개수 Kκ°€ μ£Όμ–΄μ§„λ‹€. KλŠ” 0보닀 ν¬κ±°λ‚˜ κ°™κ³ , 50보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. μ…‹μ§Έ 쀄뢀터 K개 μ€„μ—λŠ” 곡사쀑인 λ„λ‘œμ˜ 정보가 a b c d와 같이 μ£Όμ–΄μ§„λ‹€. a와 cλŠ” 0보닀 ν¬κ±°λ‚˜ κ°™κ³ , N보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄κ³ , b와 dλŠ” 0보닀 ν¬κ±°λ‚˜ κ°™κ³ , M보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. 그리고, (a, b)와 (c, d)의 κ±°λ¦¬λŠ” 항상 1이닀.

좜λ ₯

첫째 쀄에 (0, 0)μ—μ„œ (N, M)κΉŒμ§€ κ°€λŠ” 경우의 수λ₯Ό 좜λ ₯ν•œλ‹€. 이 값은 0보닀 ν¬κ±°λ‚˜ κ°™κ³ , 263-1보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

 

풀이

dp[i][j] : (i,j) κΉŒμ§€ κ°€λŠ” μ΅œλ‹¨ 경둜의 갯수

dp[i][j] = dp[i-1][j] + dp[i][j-1]

λ‹€μ΄λ‚˜λ―Ή ν”„λ‘œκ·Έλž˜λ° κΈ°λ³Έ 문제

 

이 문제의 μŸμ μ€ μ§€λ‚˜κ°ˆ 수 μ—†λŠ” λ„λ‘œμ˜ 쑴재λ₯Ό μ–΄λ–»κ²Œ λ°˜μ˜ν•˜λŠλƒλ‹€.

그리고 이 λ„λ‘œμ— λŒ€ν•œ 정보λ₯Ό μ‹œμž‘μ κ³Ό λ„μ°©μ μ΄λΌλŠ” κ΄΄μƒν•œ λ°©μ‹μœΌλ‘œ μž…λ ₯을 λ°›λŠ”λ‹€

ν•„μžλŠ” road[i][j][] ν˜•νƒœμ˜ μ‚Όμ€‘λ°°μ—΄λ‘œ λ„λ‘œλ₯Ό μ§€λ‚  수 μžˆλŠ”μ§€μ˜ μ—¬λΆ€λ₯Ό λ„£μ–΄λ’€λ‹€

 

road[i][j][0] = (i-1, j)μ—μ„œ (i,j)둜 갈 수 μžˆλŠ”μ§€ μ—¬λΆ€ => μ„Έλ‘œ(μ•„λž˜μͺ½ λ°©ν–₯) λ„λ‘œ

road[i][j][1] = (i, j-1)μ—μ„œ (i,j)둜 갈 수 μžˆλŠ”μ§€ μ—¬λΆ€ => κ°€λ‘œ(였λ₯Έμͺ½ λ°©ν–₯) λ„λ‘œ

 

그리고 μž…λ ₯은 μ‹œμž‘μ κ³Ό λ„μ°©μ μ˜ μœ„μΉ˜μ˜ μˆœμ„œλ₯Ό λ”°λ‘œ μ •ν•΄μ„œ μ£ΌλŠ”κ²Œ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ—

곡사쀑인 λ„λ‘œ 정보λ₯Ό μž…λ ₯ λ°›μ•„μ„œ μ‹œμž‘μ κ³Ό 도착점을 λͺ…ν™•νžˆ ν•˜κ³ 

방금 받은 λ„λ‘œκ°€ road[i][j][0] 인지 road[i][j][1]인지 잘 ν‘œμ‹œν•΄μ•Όν•œλ‹€

    for(int i=0; i<k; i++) {
        int a,b,c,d;
        cin >> a >> b >> c >> d;
        if(a*100+b > c*100+d) {
            int tmp;
            tmp=a; a=c; c=tmp;
            tmp=b; b=d; d=tmp;
        }
        if(a==c) {
            road[c][d][1] = false;
        } else {
            road[c][d][0] = false;
        }
    }

 

μž…λ ₯이 잘 λ˜μ—ˆλ‹€λ©΄ 이후 dp ν’€μ΄λŠ” 쉽닀.

기본적으둜 dp[i][j] = dp[i-1][j] + dp[i][j-1] μ§€λ§Œ

μœ„μ—μ„œ μ˜€λŠ” λ„λ‘œκ°€ λ§‰ν˜”λ‹€λ©΄ dp[i-1][j]λ₯Ό λ”ν•˜μ§€ μ•Šκ³ 

μ™Όμͺ½μ—μ„œ μ˜€λŠ” λ„λ‘œκ°€ λ§‰ν˜”λ‹€λ©΄ dp[i][j-1]λ₯Ό λ”ν•˜μ§€ μ•ŠμœΌλ©΄ λœλ‹€.

    // Dp 풀이
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            if(road[i][j][0]) {
                dp[i][j] += dp[i-1][j];
            }
            if(road[i][j][1]) {
                dp[i][j] += dp[i][j-1];
            }
        }
    }

 

μ½”λ“œ

//풀이 : https://whkakrkr.tistory.com

#include <iostream>
#include <vector>

using namespace std;

typedef pair<int, int> ci;
typedef long long ll;

const int INF = 101;
bool road[INF][INF][2];

int main() {
    // road μ΄ˆκΈ°ν™”
    for(int i=0; i<INF; i++) {
        for(int j=0; j<INF; j++) {
            road[i][j][0] = true;
            road[i][j][1] = true;
        }
    }
    
    // μž…λ ₯
    int n, m, k;
    cin >> n >> m >> k;
    for(int i=0; i<k; i++) {
        int a,b,c,d;
        cin >> a >> b >> c >> d;
        if(a*100+b > c*100+d) {
            int tmp;
            tmp=a; a=c; c=tmp;
            tmp=b; b=d; d=tmp;
        }
        if(a==c) {
            road[c][d][1] = false;
        } else {
            road[c][d][0] = false;
        }
    }
    
    // dp μ΄ˆκΈ°ν™”
    vector<vector<ll>>dp(n+1, vector<ll>(m+1, 0));
    dp[0][0] = 1;
    for(int i=1; i<=n; i++) {
        if(road[i][0][0]) {
            dp[i][0] = 1;
        } else {
            break;
        }
    }
    for(int j=1; j<=m; j++) {
        if(road[0][j][1]) {
            dp[0][j] = 1;
        } else {
           break;
        }
    }
    
    // Dp 풀이
    for(int i=1; i<=n; i++) {
        for(int j=1; j<=m; j++) {
            if(road[i][j][0]) {
                dp[i][j] += dp[i-1][j];
            }
            if(road[i][j][1]) {
                dp[i][j] += dp[i][j-1];
            }
        }
    }
    
    // 좜λ ₯
    cout << dp[n][m];
    
    return 0;
}
λ°˜μ‘ν˜•