- Sources:C - Goose Goose Duck
- Abstract:有 n n n 个人正在做游戏,其编号顺次为 1 , … , n 1,\dots,n 1,…,n ,当且仅当目前有 [ l i , r i ] [l_i,r_i] [li,ri] 人加入游戏时,第 i i i 个人会加入游戏。构造加入游戏的顺序方案,使加入游戏的总人数最大。
- Keywords:贪心,构造(签到题)
- Solution:将 [ l i , r i ] [l_i,r_i] [li,ri] 按左端点排序,顺次枚举右边界,判断合法的人,并将最早将不能加入(即 r i r_i ri最小)的人加入即可,此处可使用堆维护。复杂度 O ( n log n ) O(n\log n) O(nlogn)。
- Code:
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
#define endl "\n"
using pii=pair<int,int>;
struct node{
int l,r,i;
};
bool cmp(node a,node b){
if(a.l!=b.l) return a.l<b.l;
return a.r<b.r;
}
bool cmp1(pii a,pii b){
if(a.first!=b.first) return a.first>b.first;
return a.second>b.second;
}
void solve(){
int n;cin>>n;
vector<node>v(n);
for(int i=0;i<n;i++){
cin>>v[i].l>>v[i].r;
v[i].i=i+1;
}
sort(v.begin(),v.end(),cmp);
int cnt=0;
priority_queue<pii,vector<pii>,bool(*)(pii,pii)>pq(cmp1);
vector<int>ans;
for(int i=0;i<n;i++){
while(cnt<n&&v[cnt].l<=i)
pq.push({v[cnt].r,v[cnt].i}),cnt++;
while(pq.size()&&pq.top().first<i)
pq.pop();
if(pq.empty())
break;
ans.push_back(pq.top().second);
pq.pop();
}
cout<<ans.size()<<endl;
for(auto i:ans) cout<<i<<' ';
}
signed main(){
ios::sync_with_stdio(0),cin.tie(0);
int t=1;
while(t--) solve();
return 0;
}