Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

15-alstjr7437 #53

Merged
merged 2 commits into from
Mar 13, 2024
Merged

15-alstjr7437 #53

merged 2 commits into from
Mar 13, 2024

Conversation

alstjr7437
Copy link
Member

@alstjr7437 alstjr7437 commented Mar 9, 2024

πŸ”— 문제 링크

파일 ν•©μΉ˜κΈ°3

βœ”οΈ μ†Œμš”λœ μ‹œκ°„

30λΆ„

πŸ’‘ 문제 이해

일단 문제λ₯Ό μ΄ν•΄ν•˜μžλ©΄

  1. 각 νŒŒμΌμ„ ν•˜λ‚˜μ”© λ“€κ³ μ˜¨λ‹€(a,b)
  2. λ“€κ³ μ˜¨ νŒŒμΌμ„ ν•©μΉœλ‹€(c = a+b)
  3. ν•œκ°œκ°€ λ λ•ŒκΉŒμ§€ μ­‰ ν•©μΉœλ‹€.
  4. μ§€κΈˆκΉŒμ§€ λ‚˜μ™”λ˜ c와 ν•˜λ‚˜κ°€ 된 파일의 총합을 κ³„μ‚°ν•œλ‹€.

κ·Έλž˜μ„œ λ¬Έμ œκ°€
40 30 30 50 이 λ“€μ–΄μ˜€λ©΄
40 + 30 = 70 -> 70 30 50
70 + 30 = 100 -> 100 50
100 + 50 = 150 -> 150
70 + 100 + 150 = 320으둜 λ©λ‹ˆλ‹€.

κ·Έ 쀑 제일 μž‘μ€ 총합을 κ³„μ‚°ν•˜λŠ”κ±°λ‹ˆκΉŒ
μœ„μ— 뢀뢄은 κ·Έλƒ₯ 2개λ₯Ό λ”ν•˜κ³  ν•˜λ‚˜μ”© μΆ”κ°€ν•΄μ„œ λ”ν•˜λŠ” κ²½μš°μ˜€κ³  제일 μž‘μ€ 경우의 수둜 κ°€λ €λ©΄
μƒκ°ν•œ 뢀뢄이 정렬을 ν•œ 후에 μž‘μ€ 수λ₯Ό 2κ°œμ”© λ”ν•˜λ©΄ 제일 μž‘μ€ κ²½μš°κ°€ λμŠ΅λ‹ˆλ‹€.


30 30 40 50
30 + 30 = 60 -> 60 40 50
40 + 50 = 90 -> 60 90
60 + 90 = 150 -> 150
60 + 90 + 150 = 300


✨ μˆ˜λ„ μ½”λ“œ

μœ„μ™€ 같이 μƒκ°ν–ˆκ³  κ·Έλž˜μ„œ λ‚˜μ˜¨ μˆ˜λ„ μ½”λ“œλŠ”

  1. heap에 숫자λ₯Ό λͺ¨λ‘ pushν•œλ‹€.
  2. heap에 pop을 λ‘λ²ˆν•˜μ—¬μ„œ 제일 μž‘μ€ 수 2개λ₯Ό 가지고 μ˜¨λ‹€.
  3. λ‘κ°œμ˜ 수λ₯Ό λ”ν•œλ‹€.
    3-1. 3에 λ‚˜μ˜¨ 수λ₯Ό 결과에 λ”ν•œλ‹€. (κ²°κ³Ό(c)λ₯Ό 총합(answer)에 λ„£κΈ°
    3-2. 3에 λ‚˜μ˜¨ 수λ₯Ό λ‹€μ‹œ heap에 pushν•œλ‹€.(30 + 30 = 60) 60을 heap에 λ„£κΈ° -> 60, 40, 50
  4. heap이 ν•˜λ‚˜κ°€ λ λ•ŒκΉŒμ§€ λ°˜λ³΅ν•œλ‹€.

μ½”λ“œ

from heapq import *

t = int(input())

for _ in range(t):
    n = int(input()) 
    answer = 0
    heap = []

    for i in map(int, input().split()):
        heappush(heap, i)
    
    while len(heap) > 1 :
        temp = 0
        temp += heappop(heap) + heappop(heap)
        heappush(heap, temp)
        answer += temp
    print(answer)

πŸ“š μƒˆλ‘­κ²Œ μ•Œκ²Œλœ λ‚΄μš©

heap을 κΉŒλ¨Ήμ—ˆμ—ˆλŠ”λ° μ˜€λž˜λ§Œμ— λ‹€μ‹œ μ“°λ €λ‹ˆκΉŒ κ°œλ…μ„ λ‹€μ‹œ κ³΅λΆ€ν•˜λ©΄μ„œ ν–ˆλŠ”λ° μ’‹μ•˜μŠ΅λ‹ˆλ‹€!

Comment on lines +8 to +11
heap = []

for i in map(int, input().split()):
heappush(heap, i)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ΄λ ‡κ²Œ ν•˜λ‚˜μ”© 넣을 ν•„μš” 없이

heap = list(map(int, input().split()))
heapify(heap)

일반 λ¦¬μŠ€νŠΈμ— μ €μž₯ν•˜κ³  heapifyλ₯Ό μˆ˜ν–‰ν•΄μ£Όλ©΄ νž™ ꡬ쑰둜 ν•œ λ²ˆμ— λ°”κΏ”μ€λ‹ˆλ‹€. 더 μ€„μ΄μžλ©΄

heapify(heap := list(map(int, input().split())))

μ΄λ ‡κ²Œλ„ λ˜κ΅¬μš”.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ•„ν•˜ 사싀 heap을 λ‹€μ‹œ κ³΅λΆ€ν•˜λ©΄μ„œ heapifyλ₯Ό λ΄€μ—ˆλŠ”λ°
κ·Έλƒ₯ νž™κ΅¬μ‘°λ‘œ λ°”κΏ”μ£ΌλŠ”λ° listλ₯Ό λ§Œλ“€μ–΄λ‘κ³  λ‹€μ‹œ heap으둜 λ°”κΎΈλ©΄ μ‹œκ°„ λ¬Έμ œκ°€ μƒκΈΈκΉŒλ΄ κ·Έλž¬μŠ΅λ‹ˆλ‹€!!
ν˜Ήμ‹œ λ”°λ‘œ μ‹œκ°„μ— κ΄€λ ¨λœ 뢀뢄은 μ—†μ„κΉŒμš”?

Copy link

@9kyo-hwang 9kyo-hwang Mar 9, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

heap을 κ΅¬μ„±ν•˜λŠ” λ°λŠ” Sift up 방식과 Sift down 방식이 μ‘΄μž¬ν•©λ‹ˆλ‹€.

sift up 방식은 heappush κ³Όμ •μ—μ„œ λ°œκ²¬ν•  수 μžˆλŠ” ꡬ쑰둜, 주어진 λ…Έλ“œμ˜ λΆ€λͺ¨ λ…Έλ“œμ™€ 비ꡐ해 heap property λ§Œμ‘±μ‹œν‚€κ±°λ‚˜, 그렇지 μ•ŠμœΌλ©΄ root에 도착할 λ•Œ κΉŒμ§€ swapν•˜λŠ” 방법을 λœ»ν•©λ‹ˆλ‹€.
sift down 방식은 heappop κ³Όμ •μ—μ„œ λ°œκ²¬ν•  수 μžˆλŠ” ꡬ쑰둜, 주어진 λ…Έλ“œμ˜ μžμ‹ λ…Έλ“œ 쀑 keyκ°€ 큰 κ°’(or μž‘μ€ κ°’)κ³Ό 비ꡐ해 heap propertyλ₯Ό λ§Œμ‘±ν•˜κ±°λ‚˜, 그렇지 μ•ŠμœΌλ©΄ leaf에 도착할 λ•Œ κΉŒμ§€ swap ν•˜λŠ” 과정을 λœ»ν•©λ‹ˆλ‹€.

sift up은 leaf -> rootκΉŒμ§€ κ°€λŠ” 과정이고 sift down은 internal -> leafκΉŒμ§€μ˜ κ³Όμ •μž…λ‹ˆλ‹€.
λ‘˜ λ‹€ 단일 μš”μ†Œμ— λŒ€ν•΄μ„œ 연산을 μˆ˜ν–‰ν•  경우 μ‹œκ°„λ³΅μž‘λ„λŠ” $O(log N)$μ΄λ‚˜, μ™„μ „μ΄μ§„νŠΈλ¦¬ ꡬ쑰λ₯Ό κ°–λŠ” νž™μ˜ νŠΉμ„±λ•Œλ¬Έμ— 전체 μš”μ†Œμ— λŒ€ν•΄ heap을 κ΅¬μ„±ν•˜λŠ” μ‹œκ°„μ€ Sift up의 경우 $O(NlogN)$이고 Sift down의 경우 $O(N)$ μž…λ‹ˆλ‹€.

그리고 파이썬의 heapifyλŠ” Sift down λ°©μ‹μœΌλ‘œ κ΅¬ν˜„λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ heappush둜 일일이 μš”μ†Œλ₯Ό μ§‘μ–΄λ„£λŠ” 것보닀, ν•˜λ‚˜μ˜ 리슀트λ₯Ό heapifyλ₯Ό 톡해 νž™μœΌλ‘œ λ§Œλ“œλŠ” 것이 더 νš¨μœ¨μ μž…λ‹ˆλ‹€.

Build Heap μ‹œκ°„λ³΅μž‘λ„ μ΄ν•΄ν•˜κΈ°, Heap 자료ꡬ쑰 이 κ²Œμ‹œκΈ€μ„ μ°Έκ³ ν•΄λ³΄μ„Έμš”.

Comment on lines 14 to 15
temp = 0
temp += heappop(heap) + heappop(heap)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

temp = heappop(heap) + heappop(heap)

μ™œ λ°”λ‘œ ν• λ‹Ή μ•ˆν•˜μ…¨μ£ 

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ–΄λ¨Έ.. μ‹€μˆ˜λ₯Ό..

Copy link
Member

@fnzksxl fnzksxl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

였 γ…‹γ…‹ 이거 deque둜 μ •λ ¬λ•Œλ €μ„œ μ™Όμͺ½μ—μ„œ λ‘κ°œ 뽑아도 λ˜λ €λ‚˜? ν•˜κ³ 

from collections import deque
import sys

input = sys.stdin.readline

T = int(input())

for _ in range(T):
  N = int(input())
  files = deque(map(int, input().split()))
  cost = 0
  while len(files) > 1:
    files = deque(sorted(files))
    file1 = files.popleft()
    file2 = files.popleft()
    cur_cost = file1 + file2
    
    cost += cur_cost
    files.append(cur_cost)
  
  print(cost)

μ΄λ ‡κ²Œ ν•΄λ΄€λŠ”λ° μ—­μ‹œ μ‹œκ°„μ΄ˆκ³Όκ°€ λœ¨λ„€μš”. νž™μ„ μ”μ‹œλ‹€!

Copy link
Collaborator

@SeongHoonC SeongHoonC left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μ²˜μŒμ— μ‹€νŒ¨ν•˜κΈΈλž˜ μ™œκ·ΈλŸ°κ°€ ν–ˆλ”λ‹ˆ λ²”μœ„ 1,000,000 이 10000 개 더해지면 10얡이라 λ²”μœ„λ₯Ό λ„˜μ–΄κ°€λ”λΌκ΅¬μš”. κ·Έλž˜μ„œ Long 으둜 λ°”κΏ¨λ”λ‹ˆ ν†΅κ³Όν–ˆμˆ¨λ‹€.

import java.io.BufferedReader
import java.io.InputStreamReader
import java.util.PriorityQueue

fun main() {
    val br = BufferedReader(InputStreamReader(System.`in`))
    val t = br.readLine().toInt()
    repeat(t) {
        val n = br.readLine().toInt()
        val line = br.readLine().split(" ").map { it.toLong() }
        val pq = PriorityQueue<Long>().apply { addAll(line) }
        var cost: Long = 0L

        // 파일이 ν•˜λ‚˜κ°€ 되면 끝
        while (pq.size > 1) {
            val sum = pq.poll() + pq.poll()
            cost += sum
            pq.add(sum)
        }
        println(cost)
    }
}

Copy link
Collaborator

@wkdghdwns199 wkdghdwns199 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

μš°μ„ μˆœμœ„ 큐 μ“°λŠ” 법 잘 λ³Ό 수 μžˆμ–΄μ„œ μ’‹μ•˜λ˜ κ±° κ°™μ•„μš”! 민석 λ‹˜ μ½”λ“œ 보고 μ°Έκ³ ν•΄μ„œ λ‹€μ‹œ ν•œ 번 ν’€μ–΄λ΄€μŠ΅λ‹ˆλ‹Ή~

import sys 
from heapq import *
input = sys.stdin.readline
T = int(input())
for _ in range(T):
    N = int(input())
    chapters = list(map(int, input().split()))
    time_list = []
    min_time=0
    for chapter in chapters :
        heappush(time_list, chapter)
    while len(time_list) > 1 :
        temp =0 
        temp += heappop(time_list) + heappop(time_list)
        heappush(time_list, temp)
        min_time += temp
    print(min_time)

@alstjr7437 alstjr7437 merged commit 7a68047 into main Mar 13, 2024
4 checks passed
@alstjr7437 alstjr7437 deleted the 15-alstjr7437 branch March 13, 2024 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants