μ•Œκ³ λ¦¬μ¦˜/DP

[λ°±μ€€ 1106 πŸ₯‡] ν˜Έν…”

1eehyunji 2023. 11. 4. 02:42

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

 

1106번: ν˜Έν…”

첫째 쀄에 C와 ν˜•νƒμ΄κ°€ 홍보할 수 μžˆλŠ” λ„μ‹œμ˜ 개수 N이 μ£Όμ–΄μ§„λ‹€. CλŠ” 1,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄κ³ , N은 20보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” 각 λ„μ‹œμ—μ„œ 홍보할 λ•Œ

www.acmicpc.net

문제

세계적인 ν˜Έν…”μΈ ν˜•νƒ ν˜Έν…”μ˜ 사μž₯인 κΉ€ν˜•νƒμ€ μ΄λ²ˆμ— μˆ˜μž…μ„ 쑰금 늘리기 μœ„ν•΄μ„œ 홍보λ₯Ό ν•˜λ €κ³  ν•œλ‹€.

ν˜•νƒμ΄κ°€ 홍보λ₯Ό ν•  수 μžˆλŠ” λ„μ‹œκ°€ μ£Όμ–΄μ§€κ³ , 각 λ„μ‹œλ³„λ‘œ ν™λ³΄ν•˜λŠ”λ° λ“œλŠ” λΉ„μš©κ³Ό, κ·Έ λ•Œ λͺ‡ λͺ…μ˜ ν˜Έν…” 고객이 λŠ˜μ–΄λ‚˜λŠ”μ§€μ— λŒ€ν•œ 정보가 μžˆλ‹€.

예λ₯Ό λ“€μ–΄, “μ–΄λ–€ λ„μ‹œμ—μ„œ 9원을 λ“€μ—¬μ„œ ν™λ³΄ν•˜λ©΄ 3λͺ…μ˜ 고객이 λŠ˜μ–΄λ‚œλ‹€.”와 같은 정보이닀. μ΄λ•Œ, μ΄λŸ¬ν•œ 정보에 λ‚˜νƒ€λ‚œ λˆμ— μ •μˆ˜λ°° λ§ŒνΌμ„ νˆ¬μžν•  수 μžˆλ‹€. 즉, 9원을 λ“€μ—¬μ„œ 3λͺ…μ˜ 고객, 18원을 λ“€μ—¬μ„œ 6λͺ…μ˜ 고객, 27원을 λ“€μ—¬μ„œ 9λͺ…μ˜ 고객을 λŠ˜μ–΄λ‚˜κ²Œ ν•  수 μžˆμ§€λ§Œ, 3원을 λ“€μ—¬μ„œ ν™λ³΄ν•΄μ„œ 1λͺ…μ˜ 고객, 12원을 λ“€μ—¬μ„œ 4λͺ…μ˜ 고객을 λŠ˜μ–΄λ‚˜κ²Œ ν•  μˆ˜λŠ” μ—†λ‹€.

각 λ„μ‹œμ—λŠ” λ¬΄ν•œ λͺ…μ˜ 잠재적인 고객이 μžˆλ‹€. μ΄λ•Œ, ν˜Έν…”μ˜ 고객을 적어도 Cλͺ… 늘이기 μœ„ν•΄ ν˜•νƒμ΄κ°€ νˆ¬μžν•΄μ•Ό ν•˜λŠ” 돈의 μ΅œμ†Ÿκ°’μ„ κ΅¬ν•˜λŠ” ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•˜μ‹œμ˜€.

μž…λ ₯

첫째 쀄에 C와 ν˜•νƒμ΄κ°€ 홍보할 수 μžˆλŠ” λ„μ‹œμ˜ 개수 N이 μ£Όμ–΄μ§„λ‹€. CλŠ” 1,000보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄κ³ , N은 20보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€. λ‘˜μ§Έ 쀄뢀터 N개의 μ€„μ—λŠ” 각 λ„μ‹œμ—μ„œ 홍보할 λ•Œ λŒ€λŠ” λΉ„μš©κ³Ό κ·Έ λΉ„μš©μœΌλ‘œ 얻을 수 μžˆλŠ” 고객의 μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. 이 값은 100보닀 μž‘κ±°λ‚˜ 같은 μžμ—°μˆ˜μ΄λ‹€.

좜λ ₯

첫째 쀄에 문제의 정닡을 좜λ ₯ν•œλ‹€.

 

문제 풀이

  • νŠΉμ • λΉ„μš©μ„ λ“€μ—¬μ„œ 홍보λ₯Ό ν• μ§€ 말지λ₯Ό νŒλ‹¨ν•˜λŠ” 0/1 knapsack λ¬Έμ œμ΄λ―€λ‘œ DPλ₯Ό μ΄μš©ν•΄μ„œ ν’€μ—ˆλ‹€.
  • μ£Όμ˜ν•  점은 dp의 크기λ₯Ό λ‹¨μˆœνžˆ c둜 μ„ μ–Έν•˜λŠ” 것이 μ•„λ‹ˆλΌ, c+100으둜 μ„ μ–Έν•΄μ•Ό ν•œλ‹€.  
    • μ™œλƒν•˜λ©΄, c보닀 더 λ§Žμ€ μ‚¬λžŒμ— 홍보할 수 μžˆλŠ” λΉ„μš©μ΄ cλ₯Ό ν™λ³΄ν•˜λŠ” λΉ„μš©λ³΄λ‹€ 더 적게 λ“€ 수 있기 λ•Œλ¬Έμ΄λ‹€.
    • 예λ₯Ό λ“€μ–΄, cλͺ…μ—κ²Œ ν™λ³΄ν•˜λŠ” λΉ„μš©μ΄ 4원인데, 1μ›μœΌλ‘œ c+1λͺ…μ—κ²Œ 홍보할 수 μžˆλŠ” 정보가 μ£Όμ–΄μ§€λŠ” κ²½μš°λ„ 있기 λ•Œλ¬Έμ΄λ‹€.
    • c+100으둜 μž‘μ€ μ΄μœ λŠ” 문제λ₯Ό 읽어보면 홍보할 수 μžˆλŠ” μ‚¬λžŒμ˜ μ΅œλŒ€ μˆ˜κ°€ 100이기 λ•Œλ¬Έμ΄λ‹€. 
  • λ¨Όμ € 0λͺ…μ—κ²Œ 홍보할 수 μžˆλŠ” λΉ„μš©μ€ 0μ›μ΄λ―€λ‘œ dp[0]=0을 μ„ μ–Έν•΄μ€€λ‹€.
  • 그리고, info 배열에 μ €μž₯ν•΄λ‘” λΉ„μš©κ³Ό 홍보 κ°€λŠ₯ 인원을 for문으둜 νƒμƒ‰ν•˜λ©΄μ„œ for문을 λŒλ©΄μ„œ ν˜„μž¬ 탐색 쀑인 홍보 κ°€λŠ₯ 인원뢀터 c+100κΉŒμ§€ νƒμƒ‰ν•˜λ©΄μ„œ λΉ„μš©μ„ μ‚¬μš©ν•΄μ„œ ν™λ³΄ν•˜λŠ” 것과 κ·Έ 전에 κ³„μ‚°ν•œ dp κ°’ 쀑 더 μž‘μ€ κ°’μœΌλ‘œ dp 값을 κ°±μ‹ ν•΄μ€€λ‹€.
    • dp[i-people]+cost 
      • 예λ₯Ό λ“€μ–΄ 5λͺ…μ—κ²Œ ν™λ³΄ν•˜λŠ” 데에 3원이 λ“ λ‹€κ³  κ°€μ •ν–ˆμ„ λ•Œ, dp[6]λ₯Ό 계산해야 ν•œλ‹€λ©΄ 1λͺ…μ—κ²Œ ν™λ³΄ν•˜λŠ” μ΅œμ†Ÿκ°’μΈ dp[1]μ—μ„œ costλ₯Ό μΆ”κ°€ν•΄μ„œ 5λͺ…μ—κ²Œ 더 홍보할 수 μžˆλŠ” κ°’μœΌλ‘œ κ³„μ‚°ν•œ dp[6]이 기쑴의 for문을 λŒλ©΄μ„œ κ³„μ‚°λœ dp[6] κ°’(아직 κ³„μ‚°λ˜μ§€ μ•Šμ•„ 1e9)보닀 더 μž‘λ‹€λ©΄ dp[6-5]+3 κ°’μœΌλ‘œ dp[6]을 κ°±μ‹ ν•΄μ£ΌλŠ” 것이닀.
  • μ΄λŸ¬ν•œ 과정을 λͺ¨λ“  info λ°°μ—΄κ³Ό 각 λ°°μ—΄μ˜ 홍보 인원 ~ c+100 κΉŒμ§€ νƒμƒ‰ν•˜κ³ , dp κ°’μ˜ μΈλ±μŠ€κ°€ c 이상인 κ°’λ“€ 쀑 κ°€μž₯ μž‘μ€ 값을 좜λ ₯ν•˜λ©΄ λœλ‹€.
import sys

input=sys.stdin.readline
c,n=map(int, input().split(' '))
# λΉ„μš© / μ‚¬λžŒ 수
info=[list(map(int, input().split(' '))) for _ in range(n)]

# info둜 μž…λ ₯ 될 수 μžˆλŠ” μ΅œλŒ€ μ‚¬λžŒ μˆ˜κ°€ 100λͺ…이고, c보닀 더 λ§Žμ€ μ‚¬λžŒμ—κ²Œ 홍보할 수 μžˆλŠ” λΉ„μš©μ΄ μ΅œμ†Ÿκ°’μΌ 수 있음
dp=[1e9]*(c+100)
dp[0]=0
for cost, people in info:
    for i in range(people, c+100):
        dp[i]=min(dp[i-people]+cost, dp[i])

print(min(dp[c:]))