๋ฐฑ์ค€

๋ฐฑ์ค€ 1943 ๋™์ „ ๋ถ„๋ฐฐ - ํŒŒ์ด์ฌ

stoneeee 2022. 11. 23. 01:07

https://www.acmicpc.net/problem/1943

 

1943๋ฒˆ: ๋™์ „ ๋ถ„๋ฐฐ

์„ธ ๊ฐœ์˜ ์ž…๋ ฅ์ด ์ฃผ์–ด์ง„๋‹ค. ๊ฐ ์ž…๋ ฅ์˜ ์ฒซ์งธ ์ค„์— ๋™์ „์˜ ์ข…๋ฅ˜ N(1 ≤ N ≤ 100)์ด ์ฃผ์–ด์ง„๋‹ค. ๊ฐ ์ž…๋ ฅ์˜ ๋‘˜์งธ ์ค„๋ถ€ํ„ฐ N+1์งธ ์ค„๊นŒ์ง€ ๊ฐ๊ฐ์˜ ๋™์ „์˜ ๊ธˆ์•ก๊ณผ ๊ฐœ์ˆ˜๊ฐ€ ๋นˆ ์นธ์„ ์‚ฌ์ด์— ๋‘๊ณ  ์ฃผ์–ด์ง„๋‹ค. ๋‹จ, ์›

www.acmicpc.net

 

 

dp๋กœ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ƒ…์ƒ‰ ๋ฌธ์ œ์ด๋‹ค. 

Python3์„ ์ด์šฉํ•ด AC๋ฅผ ๋ฐ›์€ ์‚ฌ๋žŒ์ด ๋‹จ 4๋ช…์œผ๋กœ, ๊ทธ๋ƒฅ Pypy๋กœ ์ œ์ถœํ•˜๋Š” ๊ฒƒ์ด ์ •์‹  ๊ฑด๊ฐ•์— ์ด๋กญ๋‹ค.

๋‚œ ๊ทธ๋งˆ์ €๋„ ์‹œ๊ฐ„ ์ดˆ๊ณผ, ์˜ค๋‹ต ํŒŒํ‹ฐ๋ฅผ ํ–ˆ๋‹ค.

 

 

 

์ผ๋‹จ input์„ ๋ฐ›์œผ๋ฉด์„œ ์„ ์ƒ๋‹˜ํ•œํ…Œ ๋ฐ›์€ ์ „์ฒด ๊ธˆ์•ก์„ ๊ณ„์‚ฐํ•œ๋‹ค.

๋งŒ์•ฝ ์ „์ฒด ๊ธˆ์•ก์ด ํ™€์ˆ˜๋ผ๋ฉด ์œคํ™”์™€ ์ค€ํฌ๊ฐ€ ๋ชจ๋‘ ๋งŒ์กฑํ•  ์ˆ˜๋Š” ์—†์œผ๋ฏ€๋กœ ๊ตณ์ด ๊ณ„์‚ฐ์„ ํ•  ํ•„์š” ์—†์ด 0์„ ์ถœ๋ ฅํ•˜๊ณ  ๋„˜์–ด๊ฐ„๋‹ค.

 

๋ฐ˜๋ต์ด ๊ฐ€๋Šฅํ•œ ๊ฒฝ์šฐ์—๋Š” ์‹ค์ œ๋กœ ๋ถ„๋ฐฐ๊ฐ€ ๊ฐ€๋Šฅํ•œ์ง€ ํ™•์ธํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

์ผ๋‹จ dp๋ผ๋Š” boolean ๋ฐฐ์—ด์„ ๋งŒ๋“ค์—ˆ๋‹ค.

dp[n]์€ '์ฃผ์–ด์ง„ ๋™์ „๋“ค๋กœ n์›๋งŒํผ ์ง€๋ถˆํ•  ์ˆ˜ ์žˆ๋‹ค'๋Š” ์˜๋ฏธ์ด๋‹ค.

0์›์€ ์–ธ์ œ๊ณ  ์ง€๋ถˆํ•  ์ˆ˜ ์žˆ์œผ๋‹ˆ True๋กœ ์ดˆ๊ธฐํ™”ํ•˜๊ณ , 1์› ~ (๋ชฉํ‘œ๊ธˆ์•ก)๊นŒ์ง€๋Š” ์•„์ง ๋ชจ๋ฅด๊ฒ ์œผ๋‹ˆ False๋กœ ์ดˆ๊ธฐํ™”ํ•œ๋‹ค.

์—ฌ๊ธฐ์„œ ๋ชฉํ‘œ๊ธˆ์•ก์€ ์ „์ฒด ๊ธˆ์•ก์˜ ๋ฐ˜๋ต ๊ฐ’์ด๋‹ค.

 

coins ๋ฆฌ์ŠคํŠธ์— ๋„ฃ์–ด๋‘” ๊ฐ๊ฐ์˜ ๋™์ „์„ ์‚ดํŽด๋ณด๋ฉด์„œ dp ๋ฐฐ์—ด์„ ์—…๋ฐ์ดํŠธํ•ด์ค€๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด์„œ ์ด๋ฒˆ์— ํ™•์ธํ•  ๊ฐ’์ด [100, 1] ์ด๋ž€ ๊ฑด 100์›์งœ๋ฆฌ ๋™์ „์ด ํ•˜๋‚˜ ์žˆ๋‹ค๋Š” ์†Œ๋ฆฌ์ด๋‹ค.

๊ทธ๋Ÿผ dp ๋ฐฐ์—ด์—์„œ ๋™์ „ ๊ฐ’(100)๋ถ€ํ„ฐ ๋ชฉํ‘œ๊ธˆ์•ก๊นŒ์ง€์˜ ๋ชจ๋“  index์˜ elements๋ฅผ ๋‹ค ์‚ดํŽด๋ด์ค˜์•ผ ํ•œ๋‹ค.

dp[index - 100]์ด True๋ผ๋ฉด, (index-100) ์›์„ ์ฃผ์–ด์ง„ ๋™์ „๋“ค๋กœ ๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ์ธ๋ฐ, ๋‚˜ํ•œํ…Œ 100์› ๋™์ „์ด ํ•˜๋‚˜ ๋” ์ƒ๊ฒผ์œผ๋‹ˆ ๋‹น์—ฐํžˆ index์›๋„ ์ง€๋ถˆํ•  ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ dp[index]๋ฅผ True๋กœ ์—…๋ฐ์ดํŠธํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

๋‹ค๋งŒ ์ฃผ์˜ํ•  ์ ์ด ์žˆ๋Š”๋ฐ, ๋ฐฐ์—ด์„ ์•ž์—์„œ๋ถ€ํ„ฐ ํƒ์ƒ‰ํ•˜๋ฉด ์•ˆ ๋œ๋‹ค.

ํƒ์ƒ‰๊ณผ ๋™์‹œ์— dp ๋ฐฐ์—ด์ด ๊ฐฑ์‹ ๋˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ™์€ ๋™์ „์— ์˜ํ•ด ๊ฐฑ์‹ ๋œ ๊ฐ’์„ ๋’ค์ชฝ ์›์†Œ๊ฐ€ ์ด๋ฏธ ์ง€๋ถˆ ๊ฐ€๋Šฅํ–ˆ๋˜ ๊ฐ’์œผ๋กœ ์ฐฉ๊ฐํ•  ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉํ‘œ๊ธˆ์•ก๋ถ€ํ„ฐ ์ง€๊ธˆ ์‚ดํŽด๋ณด๋Š” ๋™์ „์˜ ๊ธˆ์•ก๊นŒ์ง€ ๊ฑฐ๊พธ๋กœ dp๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

๋งŒ์•ฝ ๊ฐ™์€ ๋™์ „์ด ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ๋ผ๋ฉด?

์ด๋ฒˆ์— ์‚ดํŽด๋ณผ ๋™์ „์ด [100, 3]๋ผ๊ณ  ํ•ด๋„ ๋™์ „์ด ํ•˜๋‚˜์ผ ๋•Œ์™€ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€๋Š” ์•Š๋‹ค.

dp[index-100]์ด True๋ผ๋ฉด dp[index]๋„ True๋กœ ๊ฐฑ์‹ ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

๋‹ค๋งŒ, dp[index+100], dp[index+200]๋„ True์ผ ํ…Œ๋‹ˆ for๋ฌธ์„ ์ด์šฉํ•ด ์ฒ˜๋ฆฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์ด๋•Œ, dp์˜ ๋ฒ”์œ„๊ฐ€ ์ „์ฒด ๊ธˆ์•ก์ด ์•„๋‹Œ ๋ฐ˜๋ต ๊ธˆ์•ก๊นŒ์ง€์ด๋ฏ€๋กœ index range๋„ ํ™•์ธํ•ด์ค˜์•ผ ํ•œ๋‹ค.

 

dp[๋ชฉํ‘œ๊ธˆ์•ก], ์ฆ‰ dp[-1]์ด True๊ฐ€ ๋˜๋Š” ๊ฑด ๋ฐ˜๋ต์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

answer์„ 1๋กœ ๊ฐฑ์‹ ํ•˜๊ณ  break ํ•ด์„œ ๋น ์ ธ๋‚˜์˜ค๋ฉด ๋˜๊ฒ ๋‹ค.

๋งŒ์•ฝ ๋๊นŒ์ง€ dp[-1]์ด False๋ผ๋ฉด answer์€ ๊ณ„์† 0์ผ ๊ฒƒ์ด๋‹ค.

์ถœ๋ ฅํ•ด์ฃผ๊ณ  ๋‹ค์Œ ํ…Œ์ŠคํŠธ์ผ€์ด์Šค๋ฅผ ์‚ดํŽด๋ณด๋ฉด ๋œ๋‹ค.

 

 

 

๋‚œ 89~92%์—์„œ ๊ณ„~์† ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋–ด์—ˆ๋‹ค.

์‹œ๊ฐ„ ์กฐ๊ธˆ์ด๋ผ๋„ ๋” ์•„๊ปด๋ณธ๋‹ค๊ณ  coins ๋ฐฐ์—ด์„ ๋‚ด๋ฆผ์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•˜๊ณ , ๋ฐ˜๋ต ๊ธˆ์•ก๋ณด๋‹ค ๋™์ „ ๊ฐ’์ด ํฌ๋ฉด break ํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ฝ”๋“œ๋ฅผ ๊ณ„์† ๋งŒ์ ธ์คฌ๋Š”๋ฐ๋„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋–ด์—ˆ๋‹ค.

๊ทธ ์ด์œ ๋Š” ๋™์ „์ด ์—ฌ๋Ÿฌ ๊ฐœ์ธ ๊ฒฝ์šฐ์— ํ•œ ๋ฒˆ์— ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๊ฑธ ํ•˜๋‚˜์”ฉ ํ™•์ธํ•ด์ค˜์„œ์˜€๋‹ค.

[100, 3]์„ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ [100, 1], [100, 1], [100, 1]๋กœ ํ™•์ธํ–ˆ์—ˆ๋‹ค.

ํ™•์ธํ•ด์•ผ ํ•  ๋ฒ”์œ„๊ฐ€ ์ปค์ง€๋ฉด ๋‹น์—ฐํžˆ ๋Š๋ฆด ์ˆ˜๋ฐ–์—.

 

 

for _ in range(3):
    total = 0 # ์„ ์ƒ๋‹˜ํ•œํ…Œ ๋ฐ›์€ ์ „์ฒด ๊ธˆ์•ก
    coins = [] 
   
    # input ๋ฐ›์œผ๋ฉด์„œ ์ „์ฒด ์•ก์ˆ˜ ๊ตฌํ•˜๊ธฐ
    for _ in range(int(input())):
        C, N = map(int, input().split())
        total += C * N
        coins.append([C, N])

    # ํ™€์ˆ˜๋Š” ๋ฐ˜์œผ๋กœ ์•ˆ๋‚˜๋ˆ ์ง > ๊ตณ์ด ํ™•์ธ ์•ˆํ•ด๋ด๋„ ๋จ
    if total % 2 == 1:
        print(0)
        continue

    total //= 2
    # dp[n]์˜ ์˜๋ฏธ == ์ฃผ์–ด์ง„ ๋™์ „๋“ค๋กœ n์›์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š”๊ฐ€?
    dp = [True] + [False] * total

    answer = 0
    for i in range(len(coins)):
        C, N = coins[i]
        
        # ๊ฑฐ๊พธ๋กœ ํƒ์ƒ‰ํ•˜๋ฉด์„œ ์ง€๋ถˆ ๊ฐ€๋Šฅํ•œ ์•ก์ˆ˜ ๊ฐฑ์‹ 
        for n in range(total, C-1, -1):
            if dp[n-C]:
                for j in range(N):
                    if n + C * j <= total:
                        dp[n + C * j] = True
                    else:
                        break
                        
        if dp[-1]: # ๋ฐ˜๋ต ๊ฐ€๋Šฅ!
            answer = 1
            break

    print(answer)