python

[μ•Œκ³ λ¦¬μ¦˜] #02 그리디 μ•Œκ³ λ¦¬μ¦˜-큰 수의 법칙 문제

Soo-minJeon 2022. 5. 3. 22:27

πŸ›  큰 수의 법칙 문제

πŸ”§  문제 

 λ‹€μ–‘ν•œ 수둜 이루어진 배열이 μžˆμ„ λ•Œ, μ£Όμ–΄μ§„ μˆ˜λ“€μ„ M번 λ”ν•˜μ—¬ κ°€μž₯ 큰 수λ₯Ό λ§Œλ“œλŠ” 법칙을 큰 수의 법칙이라고 ν•˜μž. 

단, λ°°μ—΄μ˜ νŠΉμ •ν•œ 인덱슀(번호)에 ν•΄λ‹Ήν•˜λŠ” μˆ˜κ°€ μ—°μ†ν•΄μ„œ Kλ²ˆμ„ μ΄ˆκ³Όν•˜μ—¬ λ”ν•΄μ§ˆ 수 μ—†λŠ” 것이 이 λ²•μΉ™μ˜ νŠΉμ§•μ΄λ‹€.

(μΈλ±μŠ€κ°€ λ‹€λ₯΄λ©΄ λ‹€λ₯Έ 수라고 κ°€μ •ν•œλ‹€.)

 

βœ… μž…λ ₯ 쑰건

1. 첫째 쀄에 N(2 <= N <= 1,000), M(1 <= M <= 10,000), K(1 <= L <= 10,000)의 μžμ—°μˆ˜κ°€ μ£Όμ–΄μ§€λ©°, 각 μžμ—°μˆ˜λŠ” 곡백으둜 κ΅¬λΆ„ν•œλ‹€.

2. λ‘˜μ§Έ 쀄에 N개의 μžμ—°μˆ˜κ°€ μ£Όμ–΄μ§„λ‹€. 각 μžμ—°μˆ˜λŠ” 곡백으둜 κ΅¬λΆ„ν•œλ‹€. 단, 각각의 μžμ—°μˆ˜λŠ” 1이상 10,000 μ΄ν•˜μ˜ 수둜 μ£Όμ–΄μ§„λ‹€.

3. μž…λ ₯으둜 μ£Όμ–΄μ§€λŠ” KλŠ” 항상 M보닀 μž‘κ±°λ‚˜ κ°™λ‹€.

 

βœ… 좜λ ₯ 쑰건

1. 첫째 쀄에 큰 수의 법칙에 따라 더해진 닡을 좜λ ₯ν•œλ‹€.

 

βœ… μž…λ ₯ μ˜ˆμ‹œ βœ… 좜λ ₯ μ˜ˆμ‹œ
5 8 3
2 4 5 4 6
46

 


πŸ”§ 아이디어

1) μž…λ ₯κ°’

- μš°μ„  N개의 크기λ₯Ό κ°€μ§€λŠ” 배열을 μƒμ„±ν•˜κ³ , λ‘˜μ§Έμ€„μ— μž…λ ₯받은 μžμ—°μˆ˜λ“€μ„ μ €μž₯ν•œλ‹€.

 

- μˆ˜κ°€ 같아도 μΈλ±μŠ€κ°€ λ‹€λ₯΄λ©΄ λ‹€λ₯Έ 수둜 μ—¬κΈ°κΈ° λ•Œλ¬Έμ—, λ‘˜μ§Έμ€„μ— μž…λ ₯λ°›λŠ” μˆ˜λ“€ 쀑 κ°€μž₯ 큰 μˆ˜κ°€ μ€‘λ³΅λ˜μ–΄ μžˆλŠ” 경우

K값에 상관없이 μ΅œλŒ€κ°’ * M 을 톡해 κ²°κ³Όλ₯Ό 얻을 수 μžˆλ‹€. (μ•„λž˜μ˜ 예 μ°Έκ³  - 6+6+6+6+6+6+6+6)

βœ… μž…λ ₯ μ˜ˆμ‹œ βœ… 좜λ ₯ μ˜ˆμ‹œ
5 8 3
2 4 5 6 6
48

 

- μ΅œλŒ€κ°’μ΄ λ„μΆœλ˜κΈ° μœ„ν•΄μ„œλŠ” λ‘˜μ§Έμ€„μ— μž…λ ₯λ°›λŠ” μˆ˜λ“€ 쀑 (μ΅œλŒ€κ°’ * K) + κ·Έλ‹€μŒ μ΅œλŒ€κ°’ + (μ΅œλŒ€κ°’ * M-k-1)을 계산해야 ν•œλ‹€.

βœ… μž…λ ₯ μ˜ˆμ‹œ βœ… 좜λ ₯ μ˜ˆμ‹œ
5 8 3
2 4 5 4 6
46

이 상황을 예둜 λ“€μ–΄λ³΄μžλ©΄ N = 5 / M = 8 / K = 3이닀. 

즉, N개의 μˆ«μžκ°€ λ‘˜μ§Έμ€„μ— μž…λ ₯되고 ν•œ μΈλ±μŠ€μ— ν•΄λ‹Ήν•˜λŠ” μˆ˜λŠ” μ—°μ†μœΌλ‘œ μ΅œλŒ€ 3λ²ˆκΉŒμ§€ λ”ν•΄μ§ˆ 수 있으며 총 8번의 λ§μ…ˆμ„ ν•΄μ•Ό ν•œλ‹€.

 

결과둜 μ΅œλŒ€κ°’μ„ λ‚΄μ•Ό ν•˜λ―€λ‘œ μ΅œλŒ€κ°’μ„ μ΅œλŒ€ν•œ 많이 더해야 ν•œλ‹€.

(6+6+6)=> 총 5번의 λ§μ…ˆμ΄ λ‚¨μ•˜κ³  ν•œ μΈλ±μŠ€μ— ν•΄λ‹Ήν•˜λŠ” μˆ˜λŠ” μ—°μ†μœΌλ‘œ 3λ²ˆκΉŒμ§€ λ”ν•΄μ§ˆ 수 μžˆμœΌλ‹ˆ κ·Έ λ‹€μŒμœΌλ‘œ 큰 수인 5λ₯Ό ν•œ 번 더해쀀닀.

(6+6+6)+5 => 총 4번의 λ§μ…ˆμ΄ λ‚¨μ•˜κ³  쀑간에 5λ₯Ό ν•œλ²ˆ λ”ν–ˆκΈ° λ•Œλ¬Έμ— 이제 λ‹€μ‹œ μ΅œλŒ€κ°’μΈ 6을 더할 수 있게 λ˜μ—ˆλ‹€. 

(6+6+6)+5+(6+6+6) => 총 1번의 λ§μ…ˆμ΄ λ‚¨μ•˜κ³  6을 3번 λ”ν–ˆκΈ° λ•Œλ¬Έμ— 이제 5λ₯Ό 더해 연속을 λŠμ–΄μ•Ό ν•œλ‹€.

(6+6+6)+5+(6+6+6)+5 => 총 0번의 λ§μ…ˆμ΄ 남아 κ²°κ³Όκ°’μœΌλ‘œ 46을 좜λ ₯ν•œλ‹€.

 

μ’€ 더 κ°„λ‹¨ν•˜κ²Œ 곡식화 ν•΄λ³΄μž. μœ„μ˜ 예λ₯Ό 보면 (6+6+6)+5 κ°€ λ°˜λ³΅λ˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.

M = 8일 λ•Œ, μ΅œλŒ€κ°’μΈ 6이 μ–Όλ§ŒνΌ λ”ν•΄μ§€λŠ”μ§€λ₯Ό μ•Œμ•„λ³΄μž. 

λ°˜λ³΅λ˜λŠ” (6+6+6)+5λ₯Ό ν•˜λ‚˜μ˜ 덩어리라고 μƒκ°ν•˜λ©΄ 8 μ•ˆμ—λŠ” 2κ°œκ°€ λ“€μ–΄κ°ˆ 수 μžˆλ‹€. ν•œ 덩어리 μ•ˆμ— 6이 3κ°œμ”© λ“€μ–΄μžˆμœΌλ‹ˆ 

μ΅œλŒ€κ°’μΈ 6은 총 6번 더해진닀. μ‹μœΌλ‘œ λ‚˜νƒ€λ‚΄λ©΄ M // (K+1) * K번 더해진닀.

 

λ§Œμ•½ M = 9라면? 2개의 덩어리가 듀어가고도 1이 λ‚¨λŠ”λ‹€.

이 상황은 μ΄ˆλ“±ν•™μƒλ•Œ 배운 연산인 'λ‚˜λ¨Έμ§€ μ—°μ‚°'을 ν™œμš©ν•  수 μžˆλ‹€.

9 / 4 = λͺ«μ΄ 2이고 λ‚˜λ¨Έμ§€κ°€ 1이닀. λ‚˜λ¨Έμ§€λŠ” μ ˆλŒ€ 4이상일 수 μ—†λ‹€.

λ”°λΌμ„œ μ•„λž˜μ™€ 같이 λ‚˜λ¨Έμ§€κ°€ μ–΄λ–€ μˆ˜κ°€ λ‚˜μ˜€λ“  덩어리가 2번 반볡된 ν›„μ΄λ―€λ‘œ μ΅œλŒ€κ°’μΈ 6이 λ”ν•΄μ§ˆ μˆ˜μžˆλŠ” 상황이 λœλ‹€.

[(6+6+6)+5] + [(6+6+6)+5] + ?

 

λ”°λΌμ„œ μΌλ°˜ν™”μ‹œν‚€λ©΄, 
{M // (K+1) * K} + {M % (K+1)}κ°€ λœλ‹€.

 

그럼 λ‘λ²ˆμ§Έλ‘œ 큰 값인 5λŠ” μ–Όλ§ŒνΌ λ”ν•΄μ§€λŠ”μ§€ μ•Œμ•„λ³΄μž.

M = 8μΌλ•Œ, 2번

M = 9μΌλ•Œ, 2번

M = 10μΌλ•Œ, 2번

M = 11μΌλ•Œ, 2번

M = 12μΌλ•Œ, 3번

λ”°λΌμ„œ μΌλ°˜ν™”μ‹œν‚€λ©΄ M // (K+1)이 λœλ‹€.

 

이λ₯Ό ν™œμš©ν•΄μ„œ μ½”λ“œλ₯Ό μž‘μ„±ν•΄λ³΄μž.


πŸ”§ μ½”λ“œ μž‘μ„±

# split으둜 λΆ„λ¦¬λœ N, M, Kκ°€ μ†ν•œ 배열을 mapν•¨μˆ˜λ₯Ό 톡해 int둜 ν˜•λ³€ν™˜ν•œ ν›„ 각각의 λ³€μˆ˜μ— μ €μž₯ν•œλ‹€.
N, M, K = map(int, input().split())

# list()λ₯Ό 톡해 λ‘˜μ§Έμ€„μ— μž…λ ₯λ°›λŠ” μˆ˜λ“€μ„ λ¦¬μŠ€νŠΈμ— μ €μž₯ν•œλ‹€.
InputArray = list(map(int, input().split()))

# μ΅œλŒ€κ°’κ³Ό κ·Έ λ‹€μŒμœΌλ‘œ 큰 값을 μ•Œμ•„λ‚΄κΈ° μœ„ν•΄ λ‚΄μž₯ν•¨μˆ˜ .sort()λ₯Ό μ΄μš©ν•œλ‹€
# λ‚΄λ¦Όμ°¨μˆœμœΌλ‘œ μ •λ ¬μœ„ν•΄μ„œλŠ” reverse = True λ₯Ό λ„£μ–΄μ£Όμ–΄μ•Ό 함. λ””ν΄νŠΈλŠ” μ˜€λ¦„μ°¨μˆœ
InputArray.sort(reverse=True) # .sort()ν•¨μˆ˜λŠ” 리턴값이 μ—†μŒ !!주의!!

result = 0 # 결과둜 λ°˜ν™˜ν•  λ³€μˆ˜μƒμ„±

if(InputArray[0] == InputArray[1]): # λ§Œμ•½ μ΅œλŒ€κ°’κ³Ό κ·Έ λ‹€μŒ 큰 값이 κ°™λ‹€λ©΄
    result = InputArray[0] * M
else:
    max_count = int(M / (K+1)) * K + M % (K+1) # μ΅œλŒ€κ°’μ΄ λ”ν•΄μ§ˆ 횟수
    second_count = int(M / (K+1)) # λ‘λ²ˆμ§Έ 큰 값이 λ”ν•΄μ§ˆ 횟수
    result = max_count * InputArray[0] + second_count * InputArray[1]

print(result)