Hello Ocean! 🌼

[λ°±μ€€/Python] 7579. μ•± λ³Έλ¬Έ

Algorithm

[λ°±μ€€/Python] 7579. μ•±

bba_dda 2021. 10. 12. 15:59
λ°˜μ‘ν˜•

문제

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

μš°λ¦¬λŠ” μŠ€λ§ˆνŠΈν°μ„ μ‚¬μš©ν•˜λ©΄μ„œ μ—¬λŸ¬ 가지 μ•±(App)을 μ‹€ν–‰ν•˜κ²Œ λœλ‹€. λŒ€κ°œμ˜ 경우 화면에 λ³΄μ΄λŠ” ‘μ‹€ν–‰ 쀑’인 앱은 ν•˜λ‚˜λΏμ΄μ§€λ§Œ 보이지 μ•ŠλŠ” μƒνƒœλ‘œ λ§Žμ€ 앱이 'ν™œμ„±ν™”'λ˜μ–΄ μžˆλ‹€. 앱듀이 ν™œμ„±ν™” λ˜μ–΄ μžˆλ‹€λŠ” 것은 화면에 보이지 μ•Šλ”λΌλ„ 메인 λ©”λͺ¨λ¦¬μ— μ§μ „μ˜ μƒνƒœκ°€ κΈ°λ‘λ˜μ–΄ μžˆλŠ” 것을 λ§ν•œλ‹€. ν˜„μž¬ μ‹€ν–‰ 쀑이 μ•„λ‹ˆλ”λΌλ„ μ΄λ ‡κ²Œ λ©”λͺ¨λ¦¬μ— λ‚¨κ²¨λ‘λŠ” μ΄μœ λŠ” μ‚¬μš©μžκ°€ 이전에 μ‹€ν–‰ν•˜λ˜ 앱을 λ‹€μ‹œ 뢈러올 λ•Œμ— μ§μ „μ˜ μƒνƒœλ₯Ό 메인 λ©”λͺ¨λ¦¬λ‘œλΆ€ν„° 읽어 λ“€μ—¬ μ‹€ν–‰ μ€€λΉ„λ₯Ό λΉ λ₯΄κ²Œ 마치기 μœ„ν•΄μ„œμ΄λ‹€.

 

ν•˜μ§€λ§Œ 슀마트폰의 λ©”λͺ¨λ¦¬λŠ” μ œν•œμ μ΄κΈ° λ•Œλ¬Έμ— ν•œλ²ˆμ΄λΌλ„ μ‹€ν–‰ν–ˆλ˜ λͺ¨λ“  앱을 ν™œμ„±ν™”λœ μ±„λ‘œ 메인 λ©”λͺ¨λ¦¬μ— 남겨두닀 보면 λ©”λͺ¨λ¦¬ λΆ€μ‘± μƒνƒœκ°€ 였기 쉽닀. μƒˆλ‘œμš΄ 앱을 μ‹€ν–‰μ‹œν‚€κΈ° μœ„ν•΄ ν•„μš”ν•œ λ©”λͺ¨λ¦¬κ°€ 뢀쑱해지면 슀마트폰의 μš΄μ˜μ²΄μ œλŠ” ν™œμ„±ν™” λ˜μ–΄ μžˆλŠ” μ•±λ“€ 쀑 λͺ‡ 개λ₯Ό μ„ νƒν•˜μ—¬ λ©”λͺ¨λ¦¬λ‘œλΆ€ν„° μ‚­μ œν•˜λŠ” μˆ˜λ°–μ— μ—†λ‹€. μ΄λŸ¬ν•œ 과정을 μ•±μ˜ ‘λΉ„ν™œμ„±ν™”’라고 ν•œλ‹€.

λ©”λͺ¨λ¦¬ λΆ€μ‘± μƒν™©μ—μ„œ ν™œμ„±ν™” λ˜μ–΄ μžˆλŠ” 앱듀을 λ¬΄μž‘μœ„λ‘œ ν•„μš”ν•œ λ©”λͺ¨λ¦¬λ§ŒνΌ λΉ„ν™œμ„±ν™” ν•˜λŠ” 것은 쒋은 방법이 μ•„λ‹ˆλ‹€. λΉ„ν™œμ„±ν™”λœ 앱듀을 μž¬μ‹€ν–‰ν•  경우 그만큼 μ‹œκ°„μ΄ 더 ν•„μš”ν•˜κΈ° λ•Œλ¬Έμ΄λ‹€. μ—¬λŸ¬λΆ„μ€ μ΄λŸ¬ν•œ μ•±μ˜ λΉ„ν™œμ„±ν™” 문제λ₯Ό μŠ€λ§ˆνŠΈν•˜κ²Œ ν•΄κ²°ν•˜κΈ° μœ„ν•œ ν”„λ‘œκ·Έλž¨μ„ μž‘μ„±ν•΄μ•Ό ν•œλ‹€

ν˜„μž¬ N개의 μ•±, A1, ..., AN이 ν™œμ„±ν™” λ˜μ–΄ μžˆλ‹€κ³  κ°€μ •ν•˜μž. 이듀 μ•± AiλŠ” 각각 mi λ°”μ΄νŠΈλ§ŒνΌμ˜ λ©”λͺ¨λ¦¬λ₯Ό μ‚¬μš©ν•˜κ³  μžˆλ‹€. λ˜ν•œ, μ•± Aiλ₯Ό λΉ„ν™œμ„±ν™”ν•œ 후에 λ‹€μ‹œ μ‹€ν–‰ν•˜κ³ μž ν•  경우, μΆ”κ°€μ μœΌλ‘œ λ“€μ–΄κ°€λŠ” λΉ„μš©(μ‹œκ°„ λ“±)을 μˆ˜μΉ˜ν™” ν•œ 것을 ci λΌκ³  ν•˜μž. μ΄λŸ¬ν•œ μƒν™©μ—μ„œ μ‚¬μš©μžκ°€ μƒˆλ‘œμš΄ μ•± Bλ₯Ό μ‹€ν–‰ν•˜κ³ μž ν•˜μ—¬, μΆ”κ°€λ‘œ M λ°”μ΄νŠΈμ˜ λ©”λͺ¨λ¦¬κ°€ ν•„μš”ν•˜λ‹€κ³  ν•˜μž. 즉, ν˜„μž¬ ν™œμ„±ν™” λ˜μ–΄ μžˆλŠ” μ•± A1, ..., AN μ€‘μ—μ„œ λͺ‡ 개λ₯Ό λΉ„ν™œμ„±ν™” ν•˜μ—¬ M λ°”μ΄νŠΈ μ΄μƒμ˜ λ©”λͺ¨λ¦¬λ₯Ό μΆ”κ°€λ‘œ 확보해야 ν•˜λŠ” 것이닀. μ—¬λŸ¬λΆ„μ€ κ·Έ μ€‘μ—μ„œ λΉ„ν™œμ„±ν™” ν–ˆμ„ 경우의 λΉ„μš© ci의 합을 μ΅œμ†Œν™”ν•˜μ—¬ ν•„μš”ν•œ λ©”λͺ¨λ¦¬ M λ°”μ΄νŠΈλ₯Ό ν™•λ³΄ν•˜λŠ” 방법을 μ°Ύμ•„μ•Ό ν•œλ‹€.

μž…λ ₯

μž…λ ₯은 3μ€„λ‘œ 이루어져 μžˆλ‹€. 첫 μ€„μ—λŠ” μ •μˆ˜ Nκ³Ό M이 곡백문자둜 κ΅¬λΆ„λ˜μ–΄ 주어지며, λ‘˜μ§Έ 쀄과 μ…‹μ§Έ μ€„μ—λŠ” 각각 N개의 μ •μˆ˜κ°€ 곡백문자둜 κ΅¬λΆ„λ˜μ–΄ 주어진닀. λ‘˜μ§Έ μ€„μ˜ N개의 μ •μˆ˜λŠ” ν˜„μž¬ ν™œμ„±ν™” λ˜μ–΄ μžˆλŠ” μ•± A1, ..., AN이 μ‚¬μš© 쀑인 λ©”λͺ¨λ¦¬μ˜ λ°”μ΄νŠΈ 수인 m1, ..., mN을 μ˜λ―Έν•˜λ©°, μ…‹μ§Έ μ€„μ˜ μ •μˆ˜λŠ” 각 앱을 λΉ„ν™œμ„±ν™” ν–ˆμ„ 경우의 λΉ„μš© c1, ..., cN을 μ˜λ―Έν•œλ‹€

단, 1 ≤ N ≤ 100, 1 ≤ M ≤ 10,000,000이며, 1 ≤ m1, ..., mN ≤ 10,000,000을 λ§Œμ‘±ν•œλ‹€. λ˜ν•œ, 0 ≤ c1, ..., cN ≤ 100이고, M ≤ m1 + m2 + ... + mN이닀.

좜λ ₯

ν•„μš”ν•œ λ©”λͺ¨λ¦¬ M λ°”μ΄νŠΈλ₯Ό ν™•λ³΄ν•˜κΈ° μœ„ν•œ μ•± λΉ„ν™œμ„±ν™”μ˜ μ΅œμ†Œμ˜ λΉ„μš©μ„ κ³„μ‚°ν•˜μ—¬ ν•œ 쀄에 좜λ ₯ν•΄μ•Ό ν•œλ‹€. 

풀이

DP방식 μ€‘μ—μ„œλ„ '냅색 μ•Œκ³ λ¦¬μ¦˜'을 μ΄μš©ν–ˆλ‹€. 

이전에 μ •λ¦¬ν•œ 냅색 μ•Œκ³ λ¦¬μ¦˜ 포슀트

 

[λ°±μ€€/C++] 12865. ν‰λ²”ν•œ λ°°λ‚­

문제 www.acmicpc.net/problem/12865 12865번: ν‰λ²”ν•œ λ°°λ‚­ 첫 쀄에 λ¬Όν’ˆμ˜ 수 N(1 ≤ N ≤ 100)κ³Ό μ€€μ„œκ°€ 버틸 수 μžˆλŠ” 무게 K(1 ≤ K ≤ 100,000)κ°€ 주어진닀. 두 번째 쀄뢀터 N개의 쀄에 거쳐 각 물건의 무게 W..

bba-dda.tistory.com

 

2차원 cacheλ₯Ό κ΅¬μ„±ν•΄μ„œ

cache[i][j] : 0~iκΉŒμ§€μ˜ μ•±μ—μ„œ j만큼의 cost둜 확보 κ°€λŠ₯ν•œ μ΅œλŒ€ λ©”λͺ¨λ¦¬κ°’ 

을 μ €μž₯ν•œλ‹€. 

 

점화식을 μ‚΄νŽ΄λ³΄μžλ©΄, 

i의 cost > j 이면, i번째 앱을 μ’…λ£Œν•  수 μ—†κΈ° λ•Œλ¬Έμ—, 이전단계 값을 κ·ΈλŒ€λ‘œ λ„£μ–΄μ€€λ‹€.

cache[i][j] = cache[i-1][j]

 

i의 cost <= j이면, i번째 앱을 μ’…λ£Œν•  수 있기 λ•Œλ¬Έμ—, 

i번째 μ•± μ’…λ£Œ + cache[i-1][j - (i의 cost)] vs cache[i-1][j] (i번째 μ•± μ’…λ£Œμ•ˆν•¨) 의 값을 λΉ„κ΅ν•΄μ„œ 더 큰값을 λ„£μ–΄μ£Όλ©΄ λœλ‹€. 

 

μΆ”κ°€λ‘œ λ§Œμ•½ M이 0이라면, DPμ•Œκ³ λ¦¬μ¦˜μ„ κ±°μΉ˜μ§€ μ•Šκ³  λ°”λ‘œ 0을 printν•˜κ³  μ’…λ£Œν•˜λ„λ‘ ν–ˆλ‹€. 

μ½”λ“œ

import sys
input = sys.stdin.readline

N, M = map(int, input().split())
memorys = list(map(int, input().split()))
costs = list(map(int, input().split()))
max_cost = sum(costs)
# [i][j] : 0~i번째 κΉŒμ§€μ˜ μ•±μ—μ„œ j의 cost둜 확보 κ°€λŠ₯ν•œ μ΅œλŒ€ λ©”λͺ¨λ¦¬κ°’
cache = [[0 for i in range(max_cost+1)] for j in range(N)] 
answer = max_cost

if M == 0: # M이 0이면 λ°”λ‘œ μ’…λ£Œ
    print(0)
    exit()
for j in range(max_cost+1):
    if costs[0] <= j:
        cache[0][j] = memorys[0]
for i in range(1,N):
    for j in range(max_cost+1):
        if costs[i] > j:
            cache[i][j] = cache[i-1][j]
        else:
            # i번째 μ•± μ’…λ£Œ + i-1번째 μ•±κΉŒμ§€μ—μ„œ j-i의 cost둜 얻을 수 μžˆλŠ” M의 μ΅œλŒ€κ°’κ³Ό 
            # i번째 앱을 끄지 μ•Šκ³ i-1번째 μ•± κΉŒμ§€μ—μ„œ j의 cost둜 얻을 수 μžˆλŠ” M μ΅œλŒ“κ°’ 비ꡐ
            cache[i][j] = max(memorys[i] + cache[i-1][j-costs[i]], cache[i-1][j])
        if cache[i][j] >= M:
            answer = min(answer, j)
print(answer)

κ²°κ³Ό

λ°˜μ‘ν˜•