Skip to content

Conversation

@dohyeondol1
Copy link
Contributor

@dohyeondol1 dohyeondol1 commented May 10, 2025

πŸ”— 문제 링크

ν•©λΆ„ν•΄

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

30λΆ„! μ‰¬μš΄ DP λ¬Έμ œλŠ” μ‘°κΈˆμ”© μ‹œκ°„λ‹¨μΆ•μ΄ λ˜μ–΄κ°€λŠ” 것 κ°™μ•„ κΈ°μ©λ‹ˆλ‹€ γ…Žγ…Ž

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

0λΆ€ν„° NκΉŒμ§€μ˜ μ •μˆ˜ K개λ₯Ό λ”ν•΄μ„œ κ·Έ 합이 N이 λ˜λŠ” 경우의 수λ₯Ό κ΅¬ν•˜λŠ” λ¬Έμ œμž…λ‹ˆλ‹€.

Warning

0λΆ€ν„° NκΉŒμ§€μ˜ μ •μˆ˜μ΄λ―€λ‘œ, 0을 λ”ν•΄μ„œ μ •μˆ˜μ˜ 개수λ₯Ό μ±„μš°λŠ” κ²½μš°λ„ 포함해야 ν•©λ‹ˆλ‹€.
ex) 0λΆ€ν„° 1κΉŒμ§€μ˜ μ •μˆ˜ 2개λ₯Ό λ”ν•΄μ„œ 합이 1이 λ˜λŠ” 경우 : 1+0, 0+1 = 2개

예제 μž…λ ₯인 N = 20, K = 2 와 N = 6, K = 4λ₯Ό ν™•μΈν•˜κΈ° μœ„ν•΄,
0λΆ€ν„° iκΉŒμ§€μ˜ μ •μˆ˜ k개λ₯Ό λ”ν•΄μ„œ 합이 iκ°€ λ˜λŠ” 경우의 수λ₯Ό i = 0 ~ 20, k = 0 ~ 6 의 ν…Œμ΄λΈ”λ‘œ μž‘μ„±ν•˜λ©΄ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

μ œκ°€ ν’€ λ•Œ 이만큼 많이 μ“°μ§„ μ•Šμ•˜μ§€λ§Œ... μ–΄λŠμ •λ„ 직접 경우의수λ₯Ό κ΅¬ν•΄μ„œ ν‘œλ₯Ό 그렀보면 κ·œμΉ™μ„ 찾을 수 μžˆμŠ΅λ‹ˆλ‹€.

$i β‰₯ 1$ 이고 $k β‰₯ 2$ 인 μ‘°κ±΄μ—μ„œ, λ‹€μŒ 점화식이 μ„±λ¦½ν•©λ‹ˆλ‹€.

$$ dp[i][k] = dp[i-1][k] + dp[i][k-1] $$

ν•΄λ‹Ή 점화식이 μ μš©λ˜μ§€ μ•ŠλŠ” λ²”μœ„λŠ” i = 0 μ΄κ±°λ‚˜, 0 ≀ k ≀ 1 일 κ²½μš°μž…λ‹ˆλ‹€.
μ΄λŠ” λ‹¨μˆœνžˆ λ¬Έμ œλŒ€λ‘œ μ΄ν•΄ν•˜λ©΄ μ‰¬μš΄λ°,

"0λΆ€ν„° 0κΉŒμ§€μ˜ μ •μˆ˜ k개λ₯Ό λ”ν•΄μ„œ 합이 0이 λ˜λŠ” 경우의 수"λ₯Ό κ΅¬ν•˜λŠ” κ²ƒμ΄λ―€λ‘œ, μ‚¬μš©ν•  수 μžˆλŠ” μˆ˜κ°€ 0ν•˜λ‚˜λ°–μ— μ—†μŠ΅λ‹ˆλ‹€.
λ‹€λ₯Έ μˆ˜κ°€ μ—†μœΌλ―€λ‘œ 개수만 μ±„μ›Œμ§ˆ 뿐 합은 0인 경우의 수 ν•˜λ‚˜λ§Œ μ‘΄μž¬ν•˜κ²Œ λ˜λŠ” 것이죠.

λ˜ν•œ kκ°€ 0일 경우 μ‚¬μš©ν•  수 μžˆλŠ” μ •μˆ˜κ°€ μ—†μœΌλ―€λ‘œ 경우의 μˆ˜λŠ” 아무것도 μ„ νƒν•˜μ§€ μ•ŠλŠ” 경우 ν•˜λ‚˜λ©°,

0λΆ€ν„° iκΉŒμ§€μ˜ μ •μˆ˜ λ²”μœ„μ—μ„œ, 개수 kκ°€ 1일 경우 합이 iκ°€ 될 수 μžˆλŠ” κ²½μš°λŠ” μžκΈ°μžμ‹ μ„ μ„ νƒν•˜λŠ” 경우 ν•˜λ‚˜μž…λ‹ˆλ‹€.


λ”°λΌμ„œ μœ„μ™€ 같은 λ²”μœ„μ—μ„œμ˜ μ΄ˆκΈ°κ°’μ„ μ„€μ •ν•΄μ£Όκ³ ,
μ•žμ„œ κ΅¬ν•œ 점화식을 μ΄μš©ν•΄ 각 κ²°κ³Όλ₯Ό 1,000,000,000으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό κ΅¬ν•˜λ©΄ 문제λ₯Ό ν•΄κ²°ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μˆ˜λ„ μ½”λ“œ
int main() {
    Nκ³Ό Kλ₯Ό μž…λ ₯λ°›μŒ

    크기가 (N+1) x (K+1)인 2차원 dp 배열을 0으둜 μ΄ˆκΈ°ν™”

    iλ₯Ό 0λΆ€ν„° NκΉŒμ§€ 반볡:
        dp[i][0] = 0으둜 μ„€μ •
        dp[i][1] = 1둜 μ„€μ •

    iλ₯Ό 0λΆ€ν„° KκΉŒμ§€ 반볡:
        dp[0][i] = 1둜 μ„€μ •

    iλ₯Ό 1λΆ€ν„° NκΉŒμ§€ 반볡:
        jλ₯Ό 2λΆ€ν„° KκΉŒμ§€ 반볡:
            dp[i][j]에 dp[i-1][j]와 dp[i][j-1]을 λ”ν•œ 값을 μ €μž₯
            (단, κ²°κ³ΌλŠ” 1,000,000,000으둜 λ‚˜λˆˆ λ‚˜λ¨Έμ§€λ₯Ό μ €μž₯)

    dp[N][K] 값을 좜λ ₯

    return 0
}

2차원 DPλŠ” 처음 μ‚¬μš©ν•΄λ³΄λŠ”λ° μ‰¬μš΄ λ¬Έμ œλΌμ„œ 금방 ν’€μ—ˆμŠ΅λ‹ˆλ‹€.
DPλŠ” 항상 κ·œμΉ™ μ°ΎλŠ” μž¬λ―Έμ— ν•˜λŠ” 것 κ°™μ•„μš” :D

PR을 μ“°κ³ λ³΄λ‹ˆ k = 0일 κ²½μš°λŠ” ꡳ이 배열에 ν¬ν•¨ν•˜μ§€ μ•Šμ•˜μ–΄λ„ λ¬Έμ œμ—†μ΄ ν’€μ—ˆμ„ 것 κ°™κΈ΄ ν•˜λ„€μš”

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

- μ •λ‹΅ μ—¬λΆ€μ—λŠ” 영ν–₯이 μ—†μ§€λ§Œ 잘λͺ»λœ μ΄ˆκΈ°κ°’ μ„€μ • μˆ˜μ •
@froglike6
Copy link
Collaborator

μ €λŠ” μ‘°ν•©μœΌλ‘œ μ ‘κ·Όν•΄λ΄€μŠ΅λ‹ˆλ‹€. 별과 λ§‰λŒ€λΌλŠ” 이둠을 μ‚¬μš©ν–ˆμŠ΅λ‹ˆλ‹€.
κ·Έλ ‡κ²Œ μ–΄λ €μš΄ 이둠은 μ•„λ‹ˆκ³ , "νŠΉμ • μ‘°ν•© 정리λ₯Ό λ„μΆœν•˜λŠ” 데 도움이 λ˜λŠ” κ·Έλž˜ν”½ 도ꡬ"라고 ν•˜λ„€μš” γ…Žγ…Ž.
ν•œλ²ˆ 별과 λ§‰λŒ€λ₯Ό μ΄μš©ν•΄ 문제λ₯Ό ν’€μ–΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

μ˜ˆμ‹œ: $N=6$이고, $M=4$일 λ•Œ

이 κ²½μš°μ— κ΅¬ν•˜κ³ μž ν•˜λŠ” 것은, $x_1 + x_2 + x_3 + x_4 = 6$($x_1, x_2, x_3, x_4\geq0$)이 κ°€λŠ₯ν•œ 경우의 수λ₯Ό κ΅¬ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.
별이 6개 있고, λ§‰λŒ€κ°€ 3개 μžˆμŠ΅λ‹ˆλ‹€(* * * * * * | | |). λ§‰λŒ€κ°€ 3인 μ΄μœ λŠ”, 별을 λ§‰λŒ€ 3개둜 λ‚˜λˆ„λ©΄ 4개의 κ΅¬μ—­μœΌλ‘œ λ‚˜λˆ„μ–΄μ§€κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€.

경우의 수

β”‚ β”‚ β”‚ * * * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=0,;x_4=6$μž…λ‹ˆλ‹€.
β”‚ β”‚ * β”‚ * * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=1,;x_4=5$μž…λ‹ˆλ‹€.
β”‚ β”‚ * * β”‚ * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=2,;x_4=4$μž…λ‹ˆλ‹€.
β”‚ β”‚ * * * β”‚ * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=3,;x_4=3$μž…λ‹ˆλ‹€.
β”‚ β”‚ * * * * β”‚ * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=4,;x_4=2$μž…λ‹ˆλ‹€.
β”‚ β”‚ * * * * * β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=5,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ β”‚ * * * * * * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=0,;x_3=6,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * β”‚ β”‚ * * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=0,;x_4=5$μž…λ‹ˆλ‹€.
β”‚ * β”‚ * β”‚ * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=1,;x_4=4$μž…λ‹ˆλ‹€.
β”‚ * β”‚ * * β”‚ * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=2,;x_4=3$μž…λ‹ˆλ‹€.
β”‚ * β”‚ * * * β”‚ * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=3,;x_4=2$μž…λ‹ˆλ‹€.
β”‚ * β”‚ * * * * β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=4,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ * β”‚ * * * * * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=1,;x_3=5,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * * β”‚ β”‚ * * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=2,;x_3=0,;x_4=4$μž…λ‹ˆλ‹€.
β”‚ * * β”‚ * β”‚ * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=2,;x_3=1,;x_4=3$μž…λ‹ˆλ‹€.
β”‚ * * β”‚ * * β”‚ * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=2,;x_3=2,;x_4=2$μž…λ‹ˆλ‹€.
β”‚ * * β”‚ * * * β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=2,;x_3=3,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ * * β”‚ * * * * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=2,;x_3=4,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * * * β”‚ β”‚ * * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=3,;x_3=0,;x_4=3$μž…λ‹ˆλ‹€.
β”‚ * * * β”‚ * β”‚ * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=3,;x_3=1,;x_4=2$μž…λ‹ˆλ‹€.
β”‚ * * * β”‚ * * β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=3,;x_3=2,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ * * * β”‚ * * * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=3,;x_3=3,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * * * * β”‚ β”‚ * * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=4,;x_3=0,;x_4=2$μž…λ‹ˆλ‹€.
β”‚ * * * * β”‚ * β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=4,;x_3=1,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ * * * * β”‚ * * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=4,;x_3=2,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * * * * * β”‚ β”‚ * 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=5,;x_3=0,;x_4=1$μž…λ‹ˆλ‹€.
β”‚ * * * * * β”‚ * β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=5,;x_3=1,;x_4=0$μž…λ‹ˆλ‹€.
β”‚ * * * * * * β”‚ β”‚ 인 κ²½μš°μ—λŠ”, $x_1=0,;x_2=6,;x_3=0,;x_4=0$μž…λ‹ˆλ‹€.

μ΄λ ‡κ²Œ ν•˜λ©΄, λͺ¨λ“  경우의 수λ₯Ό ꡬ할 수 μžˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ 문제λ₯Ό ν‘ΈλŠ” 방법은, ${n + k - 1 \choose k - 1}$이 λ©λ‹ˆλ‹€.

import sys, math
input = sys.stdin.readline

n,k=map(int,input().split())
print(math.comb(n+k-1,k-1)%1000000000)

근데 μ•Œκ³ λ¦¬μ¦˜ λΆ„λ₯˜μ— 쑰합둠이 μ—†λ„€μš”.. μΆ”κ°€ ν•΄μ•Όκ² μŠ΅λ‹ˆλ‹€ γ…Žγ…Ž

@dohyeondol1
Copy link
Contributor Author

@froglike6
μš°μ™......!!! μ‹ κΈ°ν•˜λ„€μš” 이런 풀이가 κ°€λŠ₯ν•˜λ‹€λ‹ˆ...
μ €λŠ” dpκ°€ 더 μ΅μˆ™ν•΄μ„œ dpκ°€ ν‘ΈλŠ”λ°μ—λŠ” λΉ¨λžμ„ 것 같은데, 쑰합을 잘 μ•Œμ•˜λ”λΌλ©΄ μ € 풀이가 훨씬 λΉ¨λžμ„μ§€λ„ λͺ¨λ₯΄κ² μŠ΅λ‹ˆλ‹€ γ…Ž

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.

생각보닀 금방 ν‘Έμ…”μ„œ μ‰¬μšΈ 쀄 μ•Œκ³  덀볐닀가 뚜까 λ§žμ•˜λ„€μš”

점화식을 κ΅¬ν•˜λ €κ³  kλŠ” κ·ΈλŒ€λ‘œ λ‘” μ±„λ‘œ n 값이 증가할 λ•Œ λ§ˆλ‹€ λ³€ν™”λ₯Ό κ΄€μ°°ν–ˆλŠ”λ°.. λ°œκ²¬ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.
μ œκ°€ μƒκ°ν•œ 이 μ ν™”μ‹μ˜ 핡심은 nκ³Ό k의 λ³€ν™”λ₯Ό λ™μ‹œμ—(?) λ³΄λŠ” 것이 핡심이 μ•„λ‹κΉŒ...ν•˜λ„€μš”
κ·Έλ ‡κ²Œ n,kλ₯Ό λ™μ‹œμ— λ³΄λ‹ˆ 점화식이 λ³΄μ΄λ”κ΅°μš”!

이후 n이 0인경우, kκ°€ 1인 경우 λͺ¨λ‘ 경우의 μˆ˜κ°€ 1μž„μ„ μ΄ˆκΈ°ν™” ν•˜μ—¬ 문제λ₯Ό ν•΄κ²°ν–ˆμŠ΅λ‹ˆλ‹΅

파이썬 coλ“œ

n, k = map(int, input().split())
dp = [[0]*(k+1) for _ in range(n+1)]
for i in range(n+1):
    dp[i][1] = 1
for i in range(k+1):
    dp[0][i] = 1
  
for i in range(1, n+1):
    for j in range(1, k+1):
        dp[i][j] = dp[i-1][j] + dp[i][j-1]
        
    
print(dp[n][k]%1000000000)

Copy link
Collaborator

@caucsejunseo caucsejunseo left a comment

Choose a reason for hiding this comment

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

확톡 문제 ν’€ 듯이 경우의 수 따라 생각해보며 μ΄ν•΄ν•˜λ©΄μ„œ ν’€λ €κ³  ν–ˆλŠ”λ° μ•ˆλ˜λ„€μš”...
λ„ν˜„λ‹˜κ°™μ€ μˆ˜ν•™ κ³ μˆ˜κ°€ μ•„λ‹ˆλ©΄ κ·Έλƒ₯ μˆ˜μ—΄ 문제 ν’€ 듯이 κ·œμΉ™λ§Œ μ°ΎλŠ”κ²Œ 더 효율적인 것 κ°™μŠ΄λ‹€.

C

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>



#define MOD 1000000000

int main() {
    int n, k;
    scanf("%d %d", &n, &k);

    int dp[201][201] = { 0 };

    for (int i = 0; i <= n; i++)
        dp[1][i] = 1;

    for (int i = 2; i <= k; i++) 
    {
        for (int j = 0; j <= n; j++) 
        {
            for (int l = 0; l <= j; l++) 
            {
                dp[i][j] = (dp[i][j] + dp[i - 1][j - l]) % MOD;
            }
        }
    }


    printf("%d\n", dp[k][n]);
    return 0;
}

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