๐Ÿ‘จโ€๐Ÿ’ป Seungineer's GitHub Contribution

๐Ÿงญ KAIST JUNGLE/Algorithm

[SW ์ •๊ธ€ 21์ผ์ฐจ] ๊ท€๋‚ฉ์  ์‚ฌ๊ณ (#DP #๋ฐฑ์ค€ 9084 #๋ฐฑ์ค€ 2294)

seungineer = seungwoo + engineer 2024. 4. 1. 03:49

์žฌ๊ท€์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•˜๋ฉด์„œ '์ ˆ์ฐจ์ง€ํ–ฅ์  ์‚ฌ๊ณ '๊ฐ€ ์•„๋‹Œ '๊ท€๋‚ฉ์  ์‚ฌ๊ณ '๋กœ ์ ‘๊ทผํ•ด์•ผ ํ•œ๋‹ค๋Š” ์–˜๊ธธ ๋“ค์—ˆ๋‹ค. ๊ทธ ๋‹น์‹œ์— ์–ด๋ ดํ’‹์ด ์ดํ•ดํ–ˆ๋˜ ๋ถ€๋ถ„์ด ๋™์ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ณต๋ถ€ํ•˜๋ฉด์„œ ์ข€ ๋” ์„ ๋ช…ํžˆ ์ดํ•ด๊ฐ€ ๋˜๋Š” ๊ฒƒ ๊ฐ™์•„ ๊ธฐ๋กํ•ด๋‘๊ณ ์ž ํ•œ๋‹ค.

๋ฐฑ์ค€ 9084

๋ฐฑ์ค€ 9084

์ด ๋ฌธ์ œ๋Š” ๋™์ „์˜ type์ด ์ฃผ์–ด์งˆ ๋•Œ ์ฃผ์–ด์ง„ ๊ธˆ์•ก์„ ๋งŒ๋“œ๋Š” ๋ชจ๋“  ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋™์ „์˜ ์ตœ๋Œ€, ์ตœ์†Œ ๊ฐœ์ˆ˜๊ฐ€ ์•„๋‹Œ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋ชจ๋‘ ํ•ฉํ•œ ๊ฐ’์„ ์ถœ๋ ฅํ•ด์•ผ ํ•œ๋‹ค.

์ฃผ์–ด์ง„ ๊ธˆ์•ก์—์„œ ์‹œ์ž‘ํ•˜์—ฌ ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ์ ˆ์ฐจ๋Œ€๋กœ ํƒ€๊ณ  ๋“ค์–ด๊ฐ€๋ฉด ๋ณต์žกํ•˜๋‹ค. ๋˜ํ•œ '์ค‘๋ณต ๋ถ€๋ถ„ ๋ฌธ์ œ'๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ DP๋ฅผ ํ™œ์šฉํ•ด๋ณธ๋‹ค.


1. ํ…Œ์ด๋ธ” ์ •์˜ํ•˜๊ธฐ


dp[i] ๋Š” 'i๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ชจ๋“  ๋ฐฉ๋ฒ•์˜ ์ˆ˜๋กœ ์ •์˜ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ •์˜ํ•ด๋ณธ ์ด์œ ๋Š” ๊ฐ„๋‹จํžˆ dp[์ฃผ์–ด์ง„ ๊ธˆ์•ก] ํ•˜๋ฉด ์ •๋‹ต์„ ์ฐพ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


2. ์ ํ™”์‹ ์ฐพ๊ธฐ

๋™์ „์˜ ์ข…๋ฅ˜๊ฐ€ 3์ข…๋ฅ˜๋ผ๊ณ  ๊ฐ€์ •ํ•  ๋•Œ '3์ข…๋ฅ˜์˜ ๋™์ „์œผ๋กœ i๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ฐฉ๋ฒ•์˜ ์ˆ˜ = โ‘ 2์ข…๋ฅ˜์˜ ๋™์ „(๋งˆ์ง€๋ง‰ ๋™์ „ ๊ธˆ์•ก ์ œ์™ธ)์œผ๋กœ i๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ฐฉ๋ฒ•์˜ ์ˆ˜ + โ‘ก3์ข…๋ฅ˜์˜ ๋™์ „์œผ๋กœ (i-๋งˆ์ง€๋ง‰ ๋™์ „ ๊ธˆ์•ก)์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๋ฐฉ๋ฒ•์˜ ์ˆ˜'๋กœ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋‹ค.

โ‘ ์€ ๋งˆ์ง€๋ง‰ ๋™์ „ ๊ธˆ์•ก์„ ์ œ์™ธ ํ›„ ๊ธˆ์•ก i๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๋‹ค. ์ฆ‰, ๋งˆ์ง€๋ง‰ ๋™์ „ ์—†์ด ๊ธˆ์•ก i๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์˜ ์ˆ˜์ด๋‹ค. โ‘ก๋Š” (i-๋งˆ์ง€๋ง‰ ๋™์ „ ๊ธˆ์•ก)์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์— ๋งˆ์ง€๋ง‰ ๋™์ „๋งŒ ์ถ”๊ฐ€ํ•  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๋‹ค์‹œ ๋งํ•ด โ‘ ์—์„œ ๋งˆ์ง€๋ง‰ ๋™์ „์ด ํฌํ•จ๋˜์ง€ ์•Š์„ ๊ฒฝ์šฐ์˜ ์ˆ˜๋Š” ๋ชจ๋‘ ๊ตฌํ–ˆ์œผ๋‹ˆ ๋งˆ์ง€๋ง‰ ๋™์ „์ด ๋ฌด์กฐ๊ฑด ํฌํ•จ๋œ ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ โ‘ก์—์„œ ์…€ ์ˆ˜ ์žˆ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด i = 6,๊ธˆ์•ก 6์„ ๋™์ „ 2, 3, 4๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ฒฝ์šฐ์˜ ์ˆ˜๋ฅผ ๊ตฌํ•ด๋ณด์ž. โ‘ ์—์„œ 2์™€ 3์„ ์ด์šฉํ•ด 6์„ ๋งŒ๋“œ๋Š” ๊ฒฝ์šฐ(2๊ฐœ) + โ‘ก๋Š” 2, 3์œผ๋กœ (6-4)๋ฅผ ๊ตฌํ•˜๋Š” ๊ฒฝ์šฐ(1๊ฐœ)๋กœ ์ด 3๊ฐœ์ž„์„ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ๋‹ค. โ‘ , โ‘ก๊ฐ€ ์–ด๋–ป๊ฒŒ ๊ณ„์‚ฐ๋˜๋Š”์ง€ ์ ˆ์ฐจ๋Œ€๋กœ ๋ณด๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํ…Œ์ด๋ธ”์„ ์ •์˜ํ•œ๋Œ€๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋ฑ‰๋Š”๋‹ค๋Š” ์ƒ๊ฐ์œผ๋กœ ๋„˜์–ด๊ฐ„๋‹ค.

3. ์ ํ™”์‹์„ ์œ„ํ•œ ์ดˆ๊ธฐ ์กฐ๊ฑด

dp ํ…Œ์ด๋ธ”์„ 0์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , dp index๊ฐ€ 0์ผ ๋•Œ(= 0์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ ๊ฒฝ์šฐ์˜ ์ˆ˜)๋ฅผ 1๋กœ ์„ค์ •(๊ฒฝ์šฐ์˜ ์ˆ˜์ด๊ธฐ์— ์•„๋ฌด๊ฒƒ๋„ ์„ ํƒ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ์กด์žฌํ•จ)ํ•œ๋‹ค.

 

t = int(input())

for _ in range(t):
    n = int(input())
    coin_types = list(map(int, input().split()))
    m = int(input())

    dp = [0] * (m+1)
    dp[0] = 1
    coin_types.sort()
    for coin in coin_types:
        for j in range(1, m+1):
            if j >= coin:
                dp[j] = dp[j] + dp[j-coin]

    print(dp[m])

 

์žฌ๊ท€์ ์œผ๋กœ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ๋•Œ๋„ ์–ด๋–ค ํ•จ์ˆ˜ ์†์˜ ํ•จ์ˆ˜ ์†์œผ๋กœ ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ์ƒํ•˜์ง€ ์•Š์•˜๋‹ค. ํ•จ์ˆ˜ ์†์˜ ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ค ๋™์ž‘์„ ํ•  ๊ฒƒ์ด๊ธฐ์— ๋ฏฟ๊ณ (?) ๋„˜์–ด๊ฐ€๋ฉด์„œ ํ•จ์ˆ˜๋ฅผ ๊ตฌ์ƒํ•˜์˜€๋‹ค. DP์˜ ์ ํ™”์‹์„ ๋„์ถœํ•˜๋Š” ๊ฒƒ๋„ ์ด์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋Š๊ปด์กŒ๋‹ค. DP ํ…Œ์ด๋ธ” ์†์œผ๋กœ ์ ˆ์ฐจ๋Œ€๋กœ ๋”ฐ๋ผ๊ฐ€๋ฉด์„œ ์ƒ๊ฐํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, DP ํ…Œ์ด๋ธ”๋กœ ์ •์˜ํ•œ ๊ฐ’์„ ๋ฑ‰์„ ๊ฒƒ์œผ๋กœ ๋ฏฟ๊ณ  ๋„˜์–ด๊ฐ„๋‹ค(๊ท€๋‚ฉ์ ์œผ๋กœ).

๋ฐฑ์ค€  2294

์ด ๋ฌธ์ œ๋Š” ์•ž ๋ฌธ์ œ์™€ ์œ ์‚ฌํ•˜๋‹ค. DP๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ฌธ์ œ๋ฅผ ํ‘ผ๋‹ค. ๋‹ค๋ฅธ ์ ์€ dp๋ฅผ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค. ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๋ถ€๋ถ„๋งŒ ์‚ดํŽด๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

...
for i in range(1, k+1):
    for coin in coin_type:
        if i >= coin:
            dp[i] = min(dp[i], dp[i-coin]+1)
        else:
            break
...

min ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์„œ dp[i]๊ฐ€ ์ž‘์€์ง€, dp[i-coin] +1์ด ์ž‘์€์ง€ ๋น„๊ตํ•œ๋‹ค. ๋น„๊ต ๋Œ€์ƒ์ด dp[i]์™€ dp[i-coin]+1์ธ๋ฐ, dp[i]๋ผ๊ณ  ํ•˜๋ฉด ๋งˆ์ง€๋ง‰ ๋™์ „์ด ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฉด์„œ i๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” ์ตœ์†Œ์˜ ๊ฐœ์ˆ˜์ด๋‹ค. dp[i-coin]์€ (i-coin)๊ธˆ์•ก๊นŒ์ง€๋กœ ๊ตฌํ•œ ์ตœ์†Œ์˜ ๊ฐœ์ˆ˜์ด๋ฏ€๋กœ ๋งˆ์ง€๋ง‰ ๋™์ „์„ ์ถ”๊ฐ€ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋˜๊ธฐ์— +1์„ ํ•œ๋‹ค. ์ด ๋‘˜ ์ค‘ ์ž‘์€ ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์•ž์„œ ๋ฌธ์ œ์˜ โ‘ , โ‘ก์™€ ๊ฑฐ์˜ ๋™์ผํ•œ ๊ตฌ์กฐ์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

 

๋ณธ ๋ฌธ์ œ์—์„œ๋„ ์žฌ๊ท€์™€ ์œ ์‚ฌํ•˜๊ฒŒ, dp[i], dp[i-coin]์€ ๊ฐ๊ฐ i์™€ i-coin์„ ๋งŒ๋“œ๋Š” ์ตœ์†Œ์˜ ๊ฐœ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค๊ณ  ๋ฏฟ๊ณ (!) (๊ท€๋‚ฉ์ ์œผ๋กœ)์ฝ”๋“œ๋ฅผ ์ง ๋‹ค.

import sys
n, k = map(int, input().split())
coin_type = []

for _ in range(n):
    coin_type.append(int(input()))

coin_type = list(set(coin_type))
coin_type.sort()

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

for i in range(1, k+1):
    for coin in coin_type:
        if i >= coin:
            dp[i] = min(dp[i], dp[i-coin]+1)
        else:
            break


if dp[k] != 54321:
    print(dp[k])
else:
    print(-1)