μ•Œκ³ λ¦¬μ¦˜

[BOJ/13164] 행볡 μœ μΉ˜μ› (그리디)

mingzoo 2023. 10. 11. 09:15

# 13164 행볡 μœ μΉ˜μ› 문제

 

행볡 μœ μΉ˜μ› 원μž₯인 νƒœμ–‘μ΄λŠ” μ–΄λŠ λ‚  Nλͺ…μ˜ 원생듀을 ν‚€ μˆœμ„œλŒ€λ‘œ 일렬둜 쀄 μ„Έμš°κ³ , 총 K개의 쑰둜 λ‚˜λˆ„λ €κ³  ν•œλ‹€. 각 μ‘°μ—λŠ” 원생이 적어도 ν•œ λͺ… μžˆμ–΄μ•Ό ν•˜λ©°, 같은 쑰에 μ†ν•œ 원생듀은 μ„œλ‘œ 인접해 μžˆμ–΄μ•Ό ν•œλ‹€. μ‘°λ³„λ‘œ μΈμ›μˆ˜κ°€ 같을 ν•„μš”λŠ” μ—†λ‹€.
μ΄λ ‡κ²Œ λ‚˜λ‰˜μ–΄μ§„ 쑰듀은 각자 단체 ν‹°μ…”μΈ λ₯Ό λ§žμΆ”λ €κ³  ν•œλ‹€. μ‘°λ§ˆλ‹€ ν‹°μ…”μΈ λ₯Ό λ§žμΆ”λŠ” λΉ„μš©μ€ μ‘°μ—μ„œ κ°€μž₯ ν‚€κ°€ 큰 원생과 κ°€μž₯ ν‚€κ°€ μž‘μ€ μ›μƒμ˜ ν‚€ 차이만큼 λ“ λ‹€. μ΅œλŒ€ν•œ λΉ„μš©μ„ 아끼고 μ‹Άμ–΄ ν•˜λŠ” νƒœμ–‘μ΄λŠ” K개의 쑰에 λŒ€ν•΄ ν‹°μ…”μΈ  λ§Œλ“œλŠ” λΉ„μš©μ˜ 합을 μ΅œμ†Œλ‘œ ν•˜κ³  μ‹Άμ–΄ν•œλ‹€. νƒœμ–‘μ΄λ₯Ό 도와 μ΅œμ†Œμ˜ λΉ„μš©μ„ κ΅¬ν•˜μž.

 

문제λ₯Ό ν’€κ²Œ 된 λ‚΄ 흐름을 μ„€λͺ…해보겠닀.

문제λ₯Ό λ¨Όμ € λ΄€μ„λ•Œ 제일 λ¨Όμ € μ μ—ˆλ˜ 것은

전체 Nλͺ… / ν‚€ μˆœμ„œ => μ˜€λ¦„μ°¨μˆœ / k개 μ‘° / 가격 : 제일큰 - 제일 μž‘μ€

이 ν‚€μ›Œλ“œλ“€λ‘œ μ‹œμž‘ν–ˆλ‹€.

 

제일 처음 문제λ₯Ό λ³Ό λ•ŒλŠ” 완전탐색 / λ°±νŠΈλž˜ν‚Ή μ΄λ ‡κ²Œ 두가지 방법이 생각났닀.

 

제일 첫 관문은 Nλͺ…을 μ–΄λ–»κ²Œ k개둜 λ‚˜λˆŒμ§€μ— λŒ€ν•œ λ°©λ²•μ΄μ—ˆλ‹€.

μ—¬κΈ°μ„œ μƒκ°λ‚œ 건 λ°±νŠΈλž˜ν‚Ήμ΄μ—ˆλ‹€.

1-nκΉŒμ§€μ˜ 숫자λ₯Ό k번 λ½‘μ•„μ„œ 합이 n이 λ˜κ²Œλ” λ§Œλ“œλŠ” λ‘œμ§μ„ μž‘μ„±ν•˜μ˜€λ‹€.

κ·Έ ν›„, λ°±νŠΈλž˜ν‚ΉμœΌλ‘œ 5λ₯Ό k개둜 λ‚˜λˆŒ 수 μžˆλŠ” 쑰합을 μ°Ύκ³ , μ˜€λ¦„μ°¨μˆœ 정렬을 ν•œ 원생듀을 λ‚˜λˆ„λŠ” 방법!으둜 κ΅¬ν˜„ν•˜λ €κ³  λ§ˆμŒλ¨Ήμ—ˆλ‹€.

 

λ‘λ²ˆμ§ΈλŠ” μ‘°ν•©μœΌλ‘œ λ‚˜λˆˆ μ›μƒλ“€μ˜ 가격을 μ–΄λ–»κ²Œ μΈ‘μ •ν•  것이냐 μ˜€λ‹€.

κ·Έ μ‘°ν•©μœΌλ‘œ λŒμ•„κ°€λ©΄μ„œ 가격을 μΈ‘μ •ν•΄μ„œ 결과적으둜 μ΅œμ†Œλ₯Ό κ΅¬ν•˜λŠ” 방법을 채택!

 

두가지 생각을 마친 λ‚˜λŠ” μ•„λž˜μ™€ 같은 μ½”λ“œλ₯Ό μž‘μ„±ν–ˆλ‹€.

n, k = tuple(map(int, input().split()))
arr = []
cnt = 0
kids = sorted(list(map(int, input().split())))
ans = max(kids)


def choose_number(curr_num):
    global cnt, ans
    if (curr_num == k and cnt == n):
        temp = 0
        temp_ans = 0
        for elem in arr:
            temp_ans += kids[elem+temp-1] - kids[temp]
            temp += elem
        ans = min(ans, temp_ans)

    for i in range(1, n):
        if (cnt+i > n):
            return
        arr.append(i)
        cnt += i
        choose_number(curr_num+1)
        cnt -= i
        arr.pop()


choose_number(0)
print(ans)

 

κ·Έ κ²°κ³Ό..

두λ‘₯

λŸ°νƒ€μž„μ—λŸ¬ λ“±μž₯...

띠둜리둜

μ—¬κΈ°μ„œλΆ€ν„° λ­”κ°€ 크게 잘λͺ»λ¨μ„ 감지..

 

잘λͺ»λΌλ„ ν•œμ°Έ 잘λͺ»λλ‹€.

일단 아이디어가 μ–΄λŠμ •λ„ ν•„μš”ν–ˆλ‹€.

k개의 쑰둜 λ‚˜λˆ„κΈ° μœ„ν•΄μ„œλŠ” N을 k-1개의 κΈ°μ€€μœΌλ‘œ μž˜λΌμ•Όν•œλ‹€.

κ·Έ 기쀀은 μ˜†μ—μžˆλŠ” μˆ˜μ™€μ˜ 차이이닀.

μˆ˜μ°¨μ΄κ°€ 큰 κΈ°μ€€μœΌλ‘œ λ‚˜λˆ μ•Ό κ·Έ 값이 κ°€κ²©μœΌλ‘œ μΈ‘μ •λ˜μ§€ μ•Šμ„κ±°κΈ° λ•Œλ¬Έμ— κ°€μž₯ 큰 차이λ₯Ό 가지고 μžˆλŠ” k-1개λ₯Ό 

 

예λ₯Ό λ“€μ–΄,

n=7 k=3

1 3 4 8 11 15 20 이라고 ν•΄λ³΄μž

>2 1 4 3 4 5

이 차이λ₯Ό μ˜€λ¦„μ°¨μˆœ ν•˜λ©΄ => 1 2 3 4 4 5이닀.

1 2 3 4 /4/ 5 -> 4와 5κ°€ κΈ°μ€€μœΌλ‘œ μ‘°κ°€ λ‚˜λ‰˜μ–΄μ Έμ•Ό λΉ„μš©μ˜ 합이 μ΅œμ†Œκ°€ λœλ‹€.

μ—¬κΈ°μ„œ 높은 μˆœμ„œλŒ€λ‘œ k-1개λ₯Ό μ œκ±°ν•œ ν›„μ˜ 합이 닡이닀.

 

μœ„ λ‘œμ§μ„ λ°˜μ˜ν•œ μ½”λ“œκ°€ μ•„λž˜μ˜ μ½”λ“œμ΄λ‹€.

import sys
input = sys.stdin.readline

n, k = map(int, input().split())
kids = list(map(int, input().split()))

ans = []
for i in range(1, n):
    ans.append(kids[i] - kids[i-1])
ans.sort(reverse=True)

print(sum(ans[k-1:]))

 

기쀀점을 μƒκ°ν•˜λŠ” λ§ˆμΈλ“œλ₯Ό κ°–μž

728x90