[BOJ] 2565. でんせん


[作成日]

  • 2022-03-21
  • [分類]

  • dp
  • LIS
  • [問題リンク]

  • https://www.acmicpc.net/problem/2565
  • [要件]


    全ての電線が交差しないように除去しなければならない電線の最小数を求める.

    [回答]


    これはLIS利用の問題です.
    アルゴリズムも久しぶりに解きましたが、LISは覚えていませんでしたが、全く思いもよらず解き、見てから応用して、すぐに理解しました.
    この問題の核心は、最も重ならない線を1本1本描けるかどうかだ.
    まず,line[N+1][2]2次元アレイにそれぞれ電柱A,Bを格納する.
    その後、LISはA基準で昇順に並べられる.
    ここで、Bを基準としてLISを取得する.
    求めたdpに最大値を見つけ,nから減算する.

    [コード]

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.StringTokenizer;
    
    
    class Main {
        static int N;
        static int[][] line;
        static int[] dp;
    
        public static void main(String[] args) throws IOException {
            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
            StringTokenizer st;
            N = Integer.parseInt(br.readLine());
    
            line = new int[N + 1][2];
            dp = new int[N + 1];
    
            // 전깃줄 입력받기
            for (int i = 1; i <= N; i++) {
                st = new StringTokenizer(br.readLine());
                for (int j = 0; j < 2; j++) {
                    line[i][j] = Integer.parseInt(st.nextToken());
                }
            }
    
            // A전봇대 오름차순 정렬
            Arrays.sort(line, new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    return Integer.compare(o1[0], o2[0]);
                }
            });
    
            // LIS 수행
            dp[1] = 1;
            for (int i = 2; i <= N; i++) {
                dp[i] = 1;
                for (int j = 1; j < i; j++) {
                    if (line[i][1] > line[j][1]) {
                        dp[i] = Math.max(dp[j] + 1, dp[i]);
                    }
                }
            }
    
            // dp값 중에서 max 찾기
            int max = Integer.MIN_VALUE;
            for(int i = 1; i <= N; i++) {
                max = Math.max(max, dp[i]);
            }
    
            System.out.println(N - max);
        }
    }