Skip to content

Conversation

@caucsejunseo
Copy link
Collaborator

@caucsejunseo caucsejunseo commented May 7, 2025

πŸ”— 문제 링크

1,2,3 λ”ν•˜κΈ°

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

1h

✨ μˆ˜λ„ μ½”λ“œ

ν˜„μ„λ‹˜μ˜ μΆ”μ²œμœΌλ‘œ ν’€μ–΄λ³΄κ²Œ λ˜μ—ˆμŠ΅λ‹ˆλ‹€!

dp문제 λ‹΅κ²Œ 사싀 μ ν™”μ‹λ§Œ μ“°λ©΄ 끝인 λ¬Έμ œμž…λ‹ˆλ‹€. μ²˜μŒμ—λŠ” μ–΄λ–»κ²Œ ν•˜λ©΄ μ•žμ˜ μˆ˜λ“€μ„ ν™œμš©ν•΄μ„œ λ‹€μŒ 수λ₯Ό λ§Œλ“€ 수 μžˆμ„κΉŒ 이해해 λ³Όλ €κ³  ν–ˆλŠ”λ° 잘 μ•ˆλ˜λ”λΌκ΅¬μš”..

κ·Έλž˜μ„œ 수λŠ₯ μˆ˜μ—΄ 문제 풀듯이 μ ‘κ·Όν•˜μ˜€μŠ΅λ‹ˆλ‹€.
image

μˆ˜μ—΄μ˜ 기본은 λ‚˜μ—΄! 그리고 κ·œμΉ™ μ°ΎκΈ°! 5κΉŒμ§€ λ‚˜μ—΄ν•΄λ³΄λ‹ˆκΉŒ κ·œμΉ™μ΄ λ³΄μ΄λ”λΌκ΅¬μš”. 6κΉŒμ§€ 해보고 이게 λ§žλ‹€κ³  ν™•μ‹ ν•˜μ˜€μŠ΅λ‹ˆλ‹€!

점화식 -->dp[k] = dp[k - 1] + dp[k - 2] + dp[k - 3]
μ•žμ˜ μ„Έ 수의 합이 κ·Έ λ‹€μŒ μˆ˜κ°€ λ©λ‹ˆλ‹€!

λ§‰μƒν•˜κ³  λ³΄λ‹ˆ λŠλ‚€κ±΄λ° 이 λ¬Έμ œλŠ” 10κΉŒμ§€λ§Œ 묻고 μžˆμœΌλ―€λ‘œ κ·Έλƒ₯ 10κΉŒμ§€ λ…Έκ°€λ‹€λ‘œ 계산 ν›„ 좜λ ₯만 해도 정닡을 맞좜 μˆ˜κ°€ μžˆμŠ΅λ‹ˆλ‹€!

κ·Έλƒ₯ν‘ΈλŠ”μ½”λ“œ

'''
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main() {
int T, n;
int dp[11] = {0};

// base cases
dp[1] = 1;  // 1
dp[2] = 2;  // 1+1, 2
dp[3] = 4;  // 1+1+1, 1+2, 2+1, 3

// 미리 dp λ°°μ—΄ 계산
for (int i = 4; i <= 10; i++) {
    dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
}

scanf("%d", &T);

for (int i = 0; i < T; i++) {
    scanf("%d", &n);
    printf("%d\n", dp[n]);
}

return 0;

}
'''

μ € 점화식을 μ΄ν•΄ν•˜μ—¬ 보자면, ν™•λ₯ κ³Ό 톡계 문제처럼, μ„Έ κ°€μ§€λ‘œ μΌ€μ΄μŠ€λ₯Ό λΆ„λ₯˜ν•˜μ—¬ 보면 μ‰½κ²Œ 이해할 수 μžˆμŠ΅λ‹ˆλ‹€.
λ§ˆμ§€λ§‰μ— 1이 λΆ™λŠ” 경우, 2κ°€ λΆ™λŠ” 경우, 그리고 3이 λΆ™λŠ” 경우!
5λΌλŠ” 숫자λ₯Ό 예둜 λ“€λ©΄

βœ… λ§ˆμ§€λ§‰μ— 1이 뢙은 경우
κ·Έ μ•žμ€ 4λ₯Ό λ§Œλ“œλŠ” λͺ¨λ“  방법 β†’ dp[4]
즉 4+1 인데 μ•žμ— 4λ₯Ό 1,2,3으둜 μ‘°ν•©ν•˜λŠ” 경우의 μˆ˜κ°€ dp[4]만큼

βœ… λ§ˆμ§€λ§‰μ— 2κ°€ 뢙은 경우
κ·Έ μ•žμ€ 3을 λ§Œλ“œλŠ” λͺ¨λ“  방법 β†’ dp[3]
즉 3+2μ—μ„œ 2κ°€ 고정이고 3을 1,2,3으둜 μ‘°ν•©ν•˜λŠ” 경우의 μˆ˜κ°€ dp[3]

βœ… λ§ˆμ§€λ§‰μ— 3이 뢙은 경우
κ·Έ μ•žμ€ 2λ₯Ό λ§Œλ“œλŠ” λͺ¨λ“  방법 β†’ dp[2]

λ”°λΌμ„œ dp[5] = dp[4] + dp[3] + dp[2] μ΄λ ‡κ²Œ ν•˜λ©΄ λͺ¨λ“  경우의 수λ₯Ό ν™•μΈν•˜κ²Œ λ©λ‹ˆλ‹€.

μˆ˜λ„μ½”λ“œ

'''
μž…λ ₯: ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ 수 T
μž…λ ₯: 각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— λŒ€ν•΄ μ •μˆ˜ n (1 ≀ n ≀ 10)

λ°°μ—΄ dp[11]을 μ„ μ–Έν•˜κ³  μ΄ˆκΈ°ν™”:
dp[1] = 1
dp[2] = 2
dp[3] = 4

count λ°°μ—΄κ³Ό answer 배열을 크기 T둜 동적 ν• λ‹Ή

각 ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€ i에 λŒ€ν•΄:
μ •μˆ˜ count[i] μž…λ ₯λ°›κΈ°

λ§Œμ•½ count[i] < 4이면:
    answer[i] = dp[count[i]]
κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄:
    dp[4]λΆ€ν„° dp[count[i]]κΉŒμ§€ μ ν™”μ‹μœΌλ‘œ μ±„μš°κΈ°:
        dp[k] = dp[k-1] + dp[k-2] + dp[k-3]
    answer[i] = dp[count[i]]

λͺ¨λ“  ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— λŒ€ν•΄:
answer[i]λ₯Ό 좜λ ₯
'''

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

점화식 μž‘μ„±

@froglike6
Copy link
Collaborator

저도 문제λ₯Ό 보자마자 dpλ₯Ό λ– μ˜¬λ ΈλŠ”λ°, λ²”μœ„λ₯Ό λ³΄λ‹ˆ 미리 ν’€μ–΄μ„œ 문제λ₯Ό 해결해도 λ˜κ² λ‹€λŠ” 생각이 λ“€μ—ˆμŠ΅λ‹ˆλ‹€. κ·Έλž˜μ„œ 파이썬으둜 dpλ₯Ό κ΅¬ν˜„ν•œ λ’€, 문제λ₯Ό ν‘ΈλŠ” μ½”λ“œλ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

DP μ½”λ“œ

dp = [0] * 11

if 1 <= 10:
    dp[1] = 1
if 2 <= 10:
    dp[2] = 2
if 3 <= 10:
    dp[3] = 4

for i in range(4, 11):
    dp[i] = dp[i-1] + dp[i-2] + dp[i-3]

T = int(input())
for _ in range(T):
    n = int(input())
    print(dp[n])

문제 풀이 μ½”λ“œ

exec("print([0,1,2,4,7,13,24,44,81,149,274][int(input())]);"*int(input()))

νŠΉμ„± 방정식을 ν†΅ν•΄μ„œ μΌλ°˜ν•­μ„ κ΅¬ν•˜λ € ν–ˆλŠ”λ°, λ³΅μ†Œμˆ˜μ™€ λΆ€λ™μ†Œμˆ˜μ  μ—°μ‚° λ•Œλ¬Έμ— ν¬κΈ°ν–ˆμŠ΅λ‹ˆλ‹€..

Copy link
Contributor

@dohyeondol1 dohyeondol1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

λƒ…λ‹€ ν˜„μš°μ§„ μ–Όκ΅΄ λœ¨λŠ”κ²Œ μ›ƒκΈ°λ„€μš” γ…‹γ…‹

사싀 μΆ”μ²œν•˜κ³  λ‚˜μ„œ 살짝 ν›„νšŒν–ˆλ˜ 건 이 문제λ₯Ό μ€€μ„œλ‹˜μ΄ 슀슀둜 μ ‘ν•˜μ§€ λͺ»ν•œ μ μž…λ‹ˆλ‹€.
μ€€μ„œλ‹˜μ΄ 아무것도 λͺ¨λ₯΄λŠ” μƒνƒœμ—μ„œ 이 문제λ₯Ό μ ‘ν–ˆλ”λΌλ©΄ μ’€ 더 μ–»μ–΄κ°€λŠ”κ²Œ λ§Žμ•˜μ„κ±°λΌκ³  μƒκ°ν–ˆκ±°λ©μš”... 문제λ₯Ό μ–΄λ–€ λ°©μ‹μœΌλ‘œ ν‘Έλƒμ˜ νžŒνŠΈκ°€ 있고 μ—†κ³ λŠ” 차이가 ν¬κ±°λ©μš”..

μ—­μ‹œ μ ν™”μ‹λ§Œ ν’€μ–΄λ‚΄λ©΄ 닡은 금방 ꡬ할 수 μžˆμ–΄μ„œ μ€€μ„œλ‹˜μ΄ ν’€ 수 μžˆμ„κ±°λΌ μƒκ°ν–ˆμŠ΅λ‹ˆλ‹€.
저도 미리 닡을 ꡬ해놓고 각 ν…ŒμŠ€νŠΈμΌ€μ΄μŠ€μ— λŒ€ν•΄ 좜λ ₯만 ν•˜λŠ” λ°©μ‹μœΌλ‘œ ν’€μ—ˆμŠ΅λ‹ˆλ‹€.

C++
#include <iostream>
using namespace std;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);
    
    int n, T;
    int dp[12];
    dp[1] = 1;
    dp[2] = 2;
    dp[3] = 4;
    for(int i = 4; i < 11; i++)
        dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
    
    cin >> T;
    while(T--) {
        cin >> n;
        cout << dp[n] << '\n';
    }
}

Copy link
Collaborator

@hadongun hadongun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

점화식을 μ°ΎλŠ” 게 ν•΅μ‹¬μ΄λ„€μš”~!
μ €λŠ” n의 크기 μ œν•œμ„ λͺ» λ΄μ„œ 리슀트의 크기λ₯Ό n+1둜 μž‘μ•˜λŠ”λ° index μ—λŸ¬κ°€ λœ¨λ”κ΅°μš”..
μ•„λ§ˆ d[0] =1 d[1]=1 d[2] = 2을 μ„ μ–Έν–ˆλŠ”λ°, n이 1인 경우 d의 인덱슀 λ²”μœ„κ°€ [0~1]μ΄μ–΄μ„œ λ¬Έμ œκ°€ μƒκΈ°λ”λΌκ΅¬μš”!
νŒŒμ΄μ¬μ—μ„œλŠ” (max(3, k + 1)) λ₯Ό ν™œμš©ν•˜λ©΄ μ΅œμ†Œ 3κΉŒμ§€λŠ” 곡간을 확보할 수 μžˆλ‹€λŠ” 것도 μ•Œκ²Œλ˜μ—ˆμ–΄μš”

Details

n = int(input())
for _ in range(n):
    k = int(input())
    d = [0] * (max(3, k + 1))
    d[0] = 1
    d[1] = 1
    d[2] = 2
    for i in range(3, k+1):
        d[i] = d[i-1] + d[i-2] + d[i-3]
    print(d[k])


    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants