[贪心][优先队列] Jzoj P6275 梦境

Description

 

题解

  • 我们先根据区间的左端点从小到大排序,将转折点也从小到大排序
  • 然后我们加入以r为关键字的小根堆,然后就贪心
  • 找到包含转折点的区间右端点离转折点最近的区间弹出,因为右端点越远,越有可能对后面的转折点提供贡献
  • 注意要把右端点比转折点还小的区间弹出

代码

 1 #include <queue>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5 #include <algorithm>
 6 #define N 200010
 7 using namespace std;
 8 struct node 
 9 {
10     int l,r;
11     bool operator <(const node &a) const { return r>a.r; }
12 }a[N];
13 priority_queue<node>Q;
14 int n,m,j=1,ans,d[N];
15 bool cmp(node a,node b) { return a.l==b.l?a.r<b.r:a.l<b.l; }
16 int main()
17 {
18     freopen("dream.in","r",stdin),freopen("dream.out","w",stdout),scanf("%d%d",&n,&m);
19     for (int i=1;i<=n;i++) scanf("%d%d",&a[i].l,&a[i].r);
20     for (int i=1;i<=m;i++) scanf("%d",&d[i]);
21     sort(a+1,a+n+1,cmp),sort(d+1,d+m+1);
22     for (int i=1;i<=m;i++)
23     {
24         while (j<=n&&a[j].l<=d[i]) Q.push(a[j++]);
25         while (!Q.empty()&&Q.top().r<d[i]) Q.pop();
26         if (!Q.empty()) ans++,Q.pop();
27     }
28     printf("%d",ans);
29 }

 

posted @ 2019-08-07 21:37  BEYang_Z  阅读(257)  评论(0编辑  收藏  举报