[BOJ] 10844번 | μ‰¬μš΄ 계단 수 (C++)

2023. 8. 26. 18:27ㆍCoding Test/BOJ

πŸ”—λ¬Έμ œ λ³΄λŸ¬κ°€κΈ°
 

10844번: μ‰¬μš΄ 계단 수

첫째 쀄에 정닡을 1,000,000,000으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό 좜λ ₯ν•œλ‹€.

www.acmicpc.net

 

πŸ§‘πŸ»‍πŸ’»ν’€μ΄ κ³Όμ •

N자리 μˆ«μžμ—μ„œ 일의 μžλ¦¬κ°€ 0 ~ 9둜 λλ‚˜λŠ” 계단 μˆ˜λ“€μ˜ 개수λ₯Ό μ•Œμ•„λ΄…μ‹œλ‹€. λ¨Όμ €, \( N = 1\)일 λ•ŒλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

 

[ N = 1 일 λ•Œ ]

i = 0 i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9
0 1
1 1 1 1 1 1 1 1

 

[ N = 2 일 λ•Œ ]

i = 0 i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9
1 1 2 2 2 2 2 2 2 1

 

[ N = 3 일 λ•Œ ]

i = 0 i = 1 i = 2 i = 3 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9
1 3 3 4 4 4 4 4 3 2

 

 

이 μ •λ„κΉŒμ§€ μ§„ν–‰ν•΄λ³΄λ‹ˆ, κ·œμΉ™μ„±μ΄ 보이기 μ‹œμž‘ν•©λ‹ˆλ‹€.

N 자리 μˆ«μžμ—μ„œ i 숫자둜 λλ‚˜λŠ” 계단 수의 개수λ₯Ό μ €μž₯ν•˜λŠ” 배열을 dp[N][i]라고 ν•œλ‹€λ©΄, κ·œμΉ™μ„±μ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

dp[N][0] = dp[N-1][1]
dp[N][i] = dp[N-1][i-1] + dp[N-1][i+1];    (i > 0 and i < 9)
dp[N][9] = dp[N-1][8]

 

즉, 동적 ν”„λ‘œκ·Έλž˜λ°μ„ μ΄μš©ν•˜μ—¬ N = 1일 λ•Œμ˜ i값듀을 λ°”νƒ•μœΌλ‘œ N = 2, N = 3의 값듀을 μ°¨λ‘€λŒ€λ‘œ μ•Œμ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

λ˜ν•œ, 동적 ν”„λ‘œκ·Έλž˜λ°μ— μ‚¬μš©ν•  배열은 \( 2 \times 10 \) 크기만 가진닀면, λͺ¨λ“  N에 λŒ€ν•œ 계단 수 개수λ₯Ό μ•Œμ•„λ‚Ό 수 μžˆμŠ΅λ‹ˆλ‹€.

 

 

이것이 μ–΄λ–»κ²Œ κ°€λŠ₯ν• κΉŒμš”? μ €λŠ” λ‹€μŒκ³Ό 같은 λ°©λ²•μœΌλ‘œ κ΅¬ν˜„ν•  수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

λ¨Όμ €, 행을 κ°€λ¦¬ν‚€λŠ” λ³€μˆ˜λ₯Ό λ‹€μŒκ³Ό 같이 2개 μ„ μ–Έν•©λ‹ˆλ‹€.

int writeBufferIndex = 0, readBufferIndex = 1;
  • writeBufferIndexλŠ” readBufferIndex의 ν–‰μ—μ„œ 읽어와 μƒˆλ‘œ 값을 μ“°κ²Œ λ˜λŠ” 행을 μ˜λ―Έν•©λ‹ˆλ‹€.
  • μœ„μ—μ„œ λ§Œλ“€μ—ˆλ˜ 점화식에 λΉ„μœ ν•˜μžλ©΄, writeBufferIndexλŠ” NreadBufferIndexλŠ” N - 1에 ν•΄λ‹Ήν•œλ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.
  • ν•œ 행에 λŒ€ν•˜μ—¬ λͺ¨λ‘ 연산이 끝났닀면, writeBufferIndex와 readBufferIndexκ°€ μ„œλ‘œ 값을 κ΅ν™˜ν•¨μœΌλ‘œμ¨, 역할을 λ°”κΏ”μ„œ λ‹€μ‹œ 연산을 μ΄μ–΄λ‚˜κ°€κ²Œ λ©λ‹ˆλ‹€.

 

N이 클수둝 2차원 λ°°μ—΄μ˜ 크기가 μ»€μ§€κ²Œ λ˜μ–΄ λ©”λͺ¨λ¦¬λ₯Ό 많이 μ“°κ²Œ λ©λ‹ˆλ‹€. μ €λŠ” μœ„ 점화식을 λ„μΆœν•˜λŠ” κ³Όμ •μ—μ„œ 행이 Nκ°œκΉŒμ§€ ν•„μš” 없을 것 κ°™λ‹€λŠ” 생각이 λ“€μ—ˆκ³ , κ·Έλž˜ν”½μŠ€ λ Œλ”λ§μ—μ„œ μ‚¬μš©λ˜λŠ” λ”λΈ” 버퍼링(Double Buffering) κΈ°λ²•μ—μ„œ 아이디어λ₯Ό μ–»μ–΄, μœ„μ™€ 같이 μ•Œκ³ λ¦¬μ¦˜μ„ κ΅¬μ„±ν•˜κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

 

βœοΈμ†ŒμŠ€ μ½”λ“œ 및 κ²°κ³Ό

#include <iostream>
#include <vector>
using namespace std;
const int MOD = 1000000000;
const int DIGIT_COUNT = 10;
const int BUFFER_COUNT = 2;

void Swap(int& x, int& y)
{
    int temp = x;
    x = y;
    y = temp;
}

int main()
{
    ios::sync_with_stdio(false);
    cout.tie(NULL); cin.tie(NULL);

    int N;
    cin >> N;

    // 1. μ΄ˆκΈ°ν™”
    vector<vector<int>> dp(BUFFER_COUNT, vector<int>(DIGIT_COUNT));
    int writeBufferIndex = 0, readBufferIndex = 1;
    int sum = 9;

    for (int i = 1; i < DIGIT_COUNT; i++)
        dp[writeBufferIndex][i] = 1;
    // ------------------------------------

    // 2. 둜직
    Swap(writeBufferIndex, readBufferIndex);
    for (int i = 1; i < N; i++)
    {
        sum = 0;

        for (int j = 0; j < DIGIT_COUNT; j++)
        {
            if (j == 0 or j == 9)
            {
                int targetIndex = (j == 0) ? j + 1 : j - 1;
                int newValue = dp[readBufferIndex][targetIndex];

                dp[writeBufferIndex][j] = newValue;
                sum = (sum + newValue) % MOD;
                continue;
            }

            dp[writeBufferIndex][j] = (dp[readBufferIndex][j - 1] + dp[readBufferIndex][j + 1]) % MOD;
            sum = (sum + dp[writeBufferIndex][j]) % MOD;
        }

        Swap(writeBufferIndex, readBufferIndex);
    }

    cout << sum;
    return 0;
}

 

728x90
λ°˜μ‘ν˜•