μΉ΄ν…Œκ³ λ¦¬ μ—†μŒ

[λ°±μ€€] 2293번: 동전 1

πŸ“ƒ λ¬Έμ œ

nκ°€μ§€ μ’…λ₯˜μ˜ 동전이 μžˆλ‹€. 각각의 동전이 λ‚˜νƒ€λ‚΄λŠ” κ°€μΉ˜λŠ” λ‹€λ₯΄λ‹€. 이 동전을 μ λ‹Ήνžˆ μ‚¬μš©ν•΄μ„œ, κ·Έ κ°€μΉ˜μ˜ 합이 k원이 λ˜λ„λ‘ ν•˜κ³  μ‹Άλ‹€. κ·Έ 경우의 수λ₯Ό κ΅¬ν•˜μ‹œμ˜€. 각각의 동전은 λͺ‡ κ°œλΌλ„ μ‚¬μš©ν•  수 μžˆλ‹€.

μ‚¬μš©ν•œ λ™μ „μ˜ ꡬ성이 같은데, μˆœμ„œλ§Œ λ‹€λ₯Έ 것은 같은 κ²½μš°μ΄λ‹€.

 

μž…λ ₯

첫째 쀄에 n, kκ°€ μ£Όμ–΄μ§„λ‹€. (1 ≤ n ≤ 100, 1 ≤ k ≤ 10,000) λ‹€μŒ n개의 μ€„μ—λŠ” 각각의 λ™μ „μ˜ κ°€μΉ˜κ°€ μ£Όμ–΄μ§„λ‹€. λ™μ „μ˜ κ°€μΉ˜λŠ” 100,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

 

좜λ ₯

첫째 쀄에 경우의 수λ₯Ό 좜λ ₯ν•œλ‹€. 경우의 μˆ˜λŠ” 2³¹λ³΄λ‹€ μž‘λ‹€.


✍ ν’€μ΄κ³Όμ •

μ²˜μŒμ— λ– μ˜¬λ¦° 생각은 수λŠ₯μ—μ„œ ν’€μ—ˆλ˜ κ²ƒμ²˜λŸΌ κ°€μž₯ 큰 μˆ˜λ“€μ„ λ¨Όμ € λ„£κ³  경우의 수λ₯Ό 찾을라고 ν–ˆμ—ˆλ‹€.

κ·Έλž˜μ„œ μž¬κ·€λ₯Ό μ“°κ±°λ‚˜ top-down 방식을 μ‚¬μš©ν•΄μ„œ 값을 μ €μž₯ν•΄λ‘˜λΌκ³  ν–ˆλŠ”λ°

잘 λͺ¨λ₯΄κ² μ–΄μ„œ λ™μ˜μƒμ„ μ°Έκ³ ν•΄μ„œ 문제λ₯Ό ν’€μ—ˆλ‹€.

 

  dp[1] dp[2] dp[3] dp[4] dp[5] dp[6] dp[7] dp[8] dp[9] dp[10]
1 1 1 1 1 1 1 1 1 1 1
2 0 1 2
(1+2)
2
(2+2,
1+1+2)
2
(2+2+1,
1+1+1+2)
         
5                    

ν–‰ - k원

μ—΄ - λ™μ „μ˜ κ°€μΉ˜

 

즉 dp(1, k)을 1원을 μ‚¬μš©ν•˜μ—¬ k원을 λ§Œλ“œλŠ” 방법이라고 ν•  수 μžˆλ‹€.

 

dp(2,k)μ—μ„œλŠ” 1,2원을 μ‚¬μš©ν•˜μ—¬ k원을 λ§Œλ“œλŠ”λ° "2원을 μΆ”κ°€ν•  λ•Œ"와 "2원을 μΆ”κ°€ν•˜μ§€ μ•Šμ„ λ•Œ"둜 λ‚˜λˆŒ 수 μžˆλ‹€.

2원을 μΆ”κ°€ν•˜μ§€ μ•Šμ„ λ•ŒλŠ” dp[k]
2원을 μΆ”κ°€ν•  λ•ŒλŠ” dp[k-2]

 => dp[k] = dp[k] + dp[k-2]

 

n, k=map(int, input().split())

v=[]
for _ in range(n):
    v.append(int(input()))

dp=[0]*(k+1)
dp[0]=1

for i in v:
    for j in range(i, k+1):
        dp[j] += dp[j-i]

print(dp[k])