•题意
二维平面上有 )$;
平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同;
问最多有多少条线段可以放置硬币。
•题解1
考虑到当 $X=x$ 时,最多有一条线段可以放置一枚硬币;
那么,我们可以从左到右查找最多有多少条线段可以放置硬币;
定义变量 $X$ 表示 $[0,X]$ 位置已放置好硬币;
既然是按照 $x$ 来的,那么我们就需要将所有可能可以放置硬币的线段按照 $l$ 升序排列,如果 $l$ 相同,按照 $r$ 升序排列;
考虑用优先级队列,首先将所有线段放入优先级队列 $q$ 中,并定义 $X=0$;
每次选择从 $q$ 的队头取出 $l$ 小的线段,判断这条线段的 $l'$ 与 $X$ 的位置关系:
①如果 $l' \leq X$,说明当前这条线段的 $[l',X]$ 位置 不能放置硬币,只能考虑 $[X+1,r']$ 位置是否还可以放置硬币;
那么,此时,我们就将 $[X+1,r_i]$ 丢到 $q$ 中,代表可能从 $[X+1,r']$ 中选择某位置放置硬币;
②如果 $l' > X$,说明 $[X,l')$ 间无可放置硬币的线段,那么我们要选择一枚硬币放置在 $l'$ 处,即当前这条线段上,并更新 $X=l'$;
•Code
View Code1 #include<bits/stdc++.h> 2 using namespace std; 3 const int maxn=1e5+50; 4 5 int n; 6 struct Heap 7 { 8 int l,r; 9 bool operator < (const Heap &obj)const 10 { 11 if(l != obj.l) 12 return l > obj.l; 13 return r > obj.r; 14 } 15 }; 16 priority_queue<Heap >q; 17 18 int Solve() 19 { 20 int X=0; 21 int ans=0; 22 while(!q.empty()) 23 { 24 Heap tmp=q.top(); 25 q.pop(); 26 27 /** 28 如果 tmp.l <= X,那么[tmp.l,X]是已求出最解的位置 29 但是[X+1,tmp.r] 还是没有放置硬币的 30 所以当前线段还是有可能在[X+1,tmp.rr]区间放置一枚硬币的 31 所以将其加入到q中 32 */ 33 if(tmp.l <= X && X+1 <= tmp.r) 34 q.push({X+1,tmp.r}); 35 else if(tmp.l > X)///如果tmp.l > X,更新ans,X 36 { 37 ans++; 38 X=tmp.l; 39 } 40 } 41 return ans; 42 } 43 int main() 44 { 45 int T; 46 scanf("%d",&T); 47 while(T--) 48 { 49 while(!q.empty()) 50 q.pop(); 51 52 scanf("%d",&n); 53 for(int i=1;i <= n;++i) 54 { 55 int l,r; 56 scanf("%d%d",&l,&r); 57 q.push({l,r}); 58 } 59 printf("%d\n",Solve()); 60 } 61 return 0; 62 }