Algorithm/ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€ - λ””νŽœμŠ€ κ²Œμž„

giraffe_ 2023. 7. 27. 13:54

https://school.programmers.co.kr/learn/courses/30/lessons/142085

 

ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€

μ½”λ“œ μ€‘μ‹¬μ˜ 개발자 μ±„μš©. μŠ€νƒ 기반의 ν¬μ§€μ…˜ λ§€μΉ­. ν”„λ‘œκ·Έλž˜λ¨ΈμŠ€μ˜ 개발자 λ§žμΆ€ν˜• ν”„λ‘œν•„μ„ λ“±λ‘ν•˜κ³ , λ‚˜μ™€ 기술 ꢁ합이 잘 λ§žλŠ” 기업듀을 λ§€μΉ­ λ°›μœΌμ„Έμš”.

programmers.co.kr

 

 

 

 

 

문제

  • μ²˜μŒμ— 병사 nλͺ…을 κ°€μ§€κ³  μžˆλ‹€. (1 ≤ n ≤ 1,000,000,000)
  • λ§€ λΌμš΄λ“œλ§ˆλ‹€ enemy[i] 마리의 적이 λ“±μž₯(1 ≤ enemy[i] ≤ 1,000,000)
    • enemy[i]μ—λŠ” i + 1 λΌμš΄λ“œμ—μ„œ κ³΅κ²©ν•΄μ˜€λŠ” 적의 μˆ˜κ°€ λ‹΄κ²¨μžˆλ‹€.
  • 남은 병사 쀑 enemy[i]λͺ… 만큼 μ†Œλͺ¨ν•˜μ—¬ enemy[i]마리의 적을 막을 수 μžˆλ‹€.
  • λ¬΄μ κΆŒμ„ μ‚¬μš©ν•˜λ©΄ λ³‘μ‚¬μ˜ μ†Œλͺ¨μ—†μ΄ ν•œ λΌμš΄λ“œμ˜ 곡격을 막을 수 μžˆλ‹€.
    • λ¬΄μ κΆŒμ€ μ΅œλŒ€ k번 μ‚¬μš©ν•  수 μžˆλ‹€. (1 ≤ k ≤ 500,000)
  • μ΅œλŒ€ λͺ‡ λΌμš΄λ“œκΉŒμ§€ 막을 수 μžˆλŠ”μ§€ κ΅¬ν•˜κΈ°

 

μž…μΆœλ ₯ μ˜ˆμ‹œ

  • μž…λ ₯ : n = 7, k= 3, enemy = {4, 2, 4, 5, 2, 3, 1}
  • κ²°κ³Ό : 5
    • 1, 3, 5 λΌμš΄λ“œμ˜ 곡격을 무적ꢌ으둜 막아내고, 2, 4 λΌμš΄λ“œμ— 각각 병사λ₯Ό 2λͺ…, 5λͺ… μ†Œλͺ¨ν•˜λ©΄ 5λΌμš΄λ“œκΉŒμ§€ 곡격을 막을 수 μžˆλ‹€.
    • 1, 3, 4번째 곡격을 무적ꢌ으둜 막아내고, 2, 5 번째 곡격에 각각 병사λ₯Ό 2λͺ…, 3λͺ… μ†Œλͺ¨ν•˜μ—¬ 5λΌμš΄λ“œκΉŒμ§€ 곡격을 막을 수 μžˆλ‹€.

 

 

 

 

 

풀이

  • μž¬κ·€ => μ‹œκ°„μ΄ˆκ³Ό

μ²˜μŒμ— λ– μ˜€λ₯Έ ν’€μ΄λŠ” μž¬κ·€μ˜€λ‹€. 뒀에 μ–΄λ–€ 애듀이 μ˜€λŠ”μ§€ λͺ¨λ₯΄κ³ , 선택할 수 μžˆλŠ” 건 λ¬΄μ κΆŒμ„ (μ“Έμ§€, μ•ˆμ“Έμ§€) 이닀. 계속 선택을 ν•˜μ—¬ 남은 병사가 μ—†κ±°λ‚˜ λ¬΄μ κΆŒμ„ λ‹€μ“°λ©΄ μ’…λ£Œν•˜κ²Œ ν•œλ‹€.

 

μˆ˜ν–‰μ‹œκ°„μ΄ 2^n인데, n이 μ΅œλŒ€ 100λ§Œμ΄λ‹ˆ μ΅œμ•…μ˜ 경우 2^100만이 κ±Έλ¦°λ‹€. μ‹œκ°„μ΄ˆκ³Όκ°€ λ‚œλ‹€.

 

λ‚΄κ°€ μ•Œκ³ μžˆλŠ” μ•Œκ³ λ¦¬μ¦˜μ„ λ– μ˜¬λ¦¬λ©° μ‹œκ°„ 초과λ₯Ό 막을 방법을 생각해야 ν•˜λŠ”λ° μ•ˆ λ– μ˜€λ₯Έλ‹€.. κ·ΈλŸ¬λ‹€κ°€ 문제의 κ²Œμ‹œνŒμ—μ„œ 힌트λ₯Ό 찾을 수 μžˆμ—ˆλ‹€. (https://school.programmers.co.kr/questions/43442)

 

자료ꡬ쑰λ₯Ό 생각해야 ν•œλ‹€.

 

  • μ΅œλŒ€νž™
    • n이 0 미만이 되면, 이전 λΌμš΄λ“œμ—μ„œ λ¬΄μ κΆŒμ„ μ¨μ„œ λ‹€μ‹œ μ‚΄μ•„λ‚œλ‹€.
    • μš°μ„ μˆœμœ„νλ‘œ κ΅¬ν˜„ν•œλ‹€. 
    • μˆ˜ν–‰μ‹œκ°„ : μ‚½μž…μ€ O(log n), μ‚­μ œλŠ” O(log n)
      • 총 n(log n) 이 κ±Έλ¦¬λ―€λ‘œ, μž¬κ·€λ‘œ κ΅¬ν˜„ν–ˆμ„ λ•Œμ˜ 2^n보닀 훨씬 μž‘λ‹€.

 

 

 

 

 

μ½”λ“œ

import java.util.*;

class Solution {
    public int solution(int n, int k, int[] enemy) {
        PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder()); //μ§€κΈˆκΉŒμ§€ 막은 병사 수 μ €μž₯
        
        int answer = 0; //μ •λ‹΅ : λͺ‡ λΌμš΄λ“œκΉŒμ§€ 막을 수 μžˆλŠ”μ§€
        for(int e : enemy) {
            n -= e; //λ³‘μ‚¬λ‘œ λ§‰μŒ
            maxHeap.add(e); //막은 병사에 μ €μž₯
            
            if(n < 0) { //남은 병사가 μ—†κ³ 
                if(k <= 0) { //무적ꢌ이 μ—†μœΌλ©΄
                    break; //λΌμš΄λ“œ μ’…λ£Œ
                }
                
                //아직 무적ꢌ이 있으면
                n += maxHeap.poll(); //μ§€λ‚˜μ˜¨ λΌμš΄λ“œ 쀑 κ°€μž₯ λ§Žμ€ 적을 λ‹€μ‹œ λΆ€ν™œμ‹œν‚€κΈ°
                k--; //무적ꢌ μ‚¬μš©
            }
            
            answer++; //λΌμš΄λ“œ 지남
        }
        
        return answer;
    }
}

 

 

 

 

 

κ²°κ³Ό

 

 

 

 

 

배운점

  • μˆ˜κ°€ λ§Žμ„ λ•ŒλŠ” 순회말고 자료ꡬ쑰λ₯Ό 생각해보기
  • μ΅œλŒ€νž™ : μš°μ„ μˆœμœ„νλ₯Ό μ΄μš©ν•΄μ„œ κ΅¬ν˜„ν•  수 있음
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());

 

  • μš°μ„ μˆœμœ„ 큐의 μˆ˜ν–‰μ‹œκ°„ : μ‚½μž…μ€ O(log n), μ‚­μ œλŠ” O(log n)