[Java] Greedy algorithm

2024. 2. 18. 16:20Algorithm/with Java

1. Greedy algorithm

 

  • 문제 상황
    : 최적해를 구하기 위해서 사용되는 근사적인 방법. (보통 최대 또는 최소를 구한다.)
  • 원리
    : 여러 경우 중 하나를 결정해야 할 때마다 그 순간에 최적이라고 생각되는 것을 선택해 나가는 방식으로 진행하여 최종적인 해답에 도달한다.
  • 한계
    : 각 선택 시점에서 이루어지는 결정은 지역적으로 최적이지만, 그 선택들을 계속 수집하여 최종적인 해답을 만들었을 때, 그것이 반드시 최적이라고 보장할 수 없다.
    : 대부분의 그리디 알고리즘은 몇몇 단순하고 제한된 문제에 적용된다.
  • 필수 조건
    : 원문제의 최적해 = 탐욕적 선택 속성 + 최적 부분 구조
    : 탐욕적 선택이 최적해로 이어진다는 것을 증명해야 한다. (탐욕적 선택 속성)
    : 하나의 선택을 풀면 하나의 하위 문제가 남는다. (최적 부분 구조)

 


2. knapsack

 

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)

www.acmicpc.net

  • 문제 상황
    : 주어진 조건을 만족하는 최적화된 부분집합을 구하는 문제.

 


가. 종류

 

  • 0-1 knapsack
    • 물건을 쪼갤 수 없는 경우
    • 완전탐색, DP
  • Fractional Knapsack
    • 물건을 부분적으로 담는 것이 허용되는 문제
    • 그리디, 완전탐색, DP

 


3. Activity-Selection Problem

 

 

1931번: 회의실 배정

(1,4), (5,7), (8,11), (12,14) 를 이용할 수 있다.

www.acmicpc.net

  • 활동 선택 문제
  • 문제 상황
    : 시작시간과 종료시간을 가진 활동들 있을 때 서로 겹치지 않는 선에서 최대한 많은 활동을 수행하는 방법.
    : 양립 가능한 활동들의 크기가 최대가 되는 부분집합을 선택하는 문제
  • 원리
    : 종료 시간 순으로 활동들을 정렬한다. ← O(NlogN)

 


가. 문제

 

  • 회의실 선택
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Main {

    static class Meeting implements Comparable<Meeting> {
        int start, end;

        Meeting (int start, int end){
            this.start = start;
            this.end = end;
        }

        @Override
        public int compareTo(Meeting o) {
            return this.end != o.end ? this.end - o.end : this.start - o.start;
        }

        @Override
        public String toString() {
            return "start : " + this.start + " end : " + this.end;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt();
        Meeting[] meetings = new Meeting[N];

        for(int i=0; i<N; i++) {
            meetings[i] = new Meeting(sc.nextInt(), sc.nextInt());
        }

        Arrays.sort(meetings);

        List<Meeting> list = new ArrayList<>();
        list.add(meetings[0]);
        for(int j=1; j<N; j++) {
            if(list.get(list.size()-1).end <= meetings[j].start) {
                list.add(meetings[j]);
            }
        }

        System.out.println(list.size());
        //for(Meeting meeting : list) {
        //    System.out.println(meeting);
        //}
        sc.close();
    }

}

 


4. 동전 자판기

 

 

JUNGOL

code_blocks 코드 보기

www.jungol.co.kr

  • 문제 상황
    : 주어진 조건을 만족하는 최적화된 부분집합을 구하는 문제.

 


5. 그 외

 

알고리즘 문제 상황 원리
슬라이딩 윈도우 주어진 자료구조의 일정 구간을 순차적으로 이동하면서 연산을 수행할 때. 윈도우를 한 칸씩 이동시키면서 새로운 요소를 추가하고, 이전 요소를 제거하여 부분 문제를 해결한다.
Prim N 개의 노드에 대한 최소 신장 트리(MST)를 찾는다. 서브트리를 확장하면서 MST를 찾는다.
Kruskal N 개의 노드에 대한 최소 신장 트리(MST)를 찾는다. 싸이클이 없는 서브 그래프를 확장하면서 MST를 찾는다.
Dijkstra 주어진 정점에서 다른 정점들에 대한 최단 경로를 찾는다. 주어진 정점에서 가장 가까운 정점을 찾고, 그 다음을 정점을 반복해서 찾는다.

 

추후에 하나씩 따로 다룰 예정.

 


'Algorithm > with Java' 카테고리의 다른 글

[알고리즘] 1828. 냉장고  (0) 2024.02.19
[알고리즘] 1931. 회의실 배정  (0) 2024.02.18
[알고리즘] 풀었던 문제 (240208)  (0) 2024.02.18
[알고리즘] 4012. 요리사  (0) 2024.02.18
[알고리즘] 1861. 정사각형 방  (0) 2024.02.18