1. 程式人生 > >1672 區間交(貪心)

1672 區間交(貪心)

1672 區間交
1 秒 131,072 KB 40 分 4 級題

思路:

先按照區間左端點排序
然後維護一個優先佇列,存放右端點

迴圈m個區間
佇列共三種操作

  • 把每個區間的右端點加入
  • 如果區間左端點>佇列的值,彈出
  • size>k時,彈出至k個
  • 佇列每次size為k時,計算區間的和,佇列第一個-(當前左端點-1)取最大值

    程式碼:

package _51_node.greedy;

import java.util.Arrays;
import java.util.PriorityQueue;
import java.util.Scanner;

public class ex_1672 {
    /**
     * 1672 區間交
     * 1 秒  131,072 KB 40 分 4 級題
     * @param args
     */
    public static void main(String[] args) {
        Scanner cin = new Scanner(System.in);
        int n, k, m, x;
        n = cin.nextInt();
        k = cin.nextInt();
        m = cin.nextInt();
        long[] sum = new long[n+1];
        PriorityQueue<Integer> q = new PriorityQueue<>();
        Pair[] pair = new Pair[m];
        for (int i = 1; i <= n; i++) {
            x = cin.nextInt();
            sum[i] = sum[i - 1] + x;
        }
        for (int i = 0; i < m; i++) {
            pair[i] = new Pair(cin.nextInt(), cin.nextInt());
        }
        Arrays.sort(pair);
        long ans = 0;
        for (int i = 0; i < m; i++) {
            q.add(pair[i].r);
            while (!q.isEmpty()) { //剔除沒有相交區域的
                if (q.peek() < pair[i].l) q.poll();
                else break;
            }
            while (q.size() > k) q.poll();//去除小區間
            if (q.size() == k) ans = Math.max(ans, sum[q.peek()] - sum[pair[i].l-1]);
        }
        System.out.println(ans);
    }

    static class Pair implements Comparable<Pair> {
        int l;
        int r;

        public Pair(int l, int r) {
            this.l = l;
            this.r = r;
        }

        @Override
        public int compareTo(Pair o) {
            if (l > o.l) return 1;
            return -1;
        }
    }
}