题目链接:传送门
题意:
邀请n个人去参加聚会,对于第i个人只有当去人数大于等于li,小于等于ri的时候这个人才会去参加聚会,
让你确定一个邀请的顺序,使得最后去参加聚会的人数最多。
分析:
读完题目后就感觉这个题是个贪心,但是没有想好怎么去维护,比赛完了看完题解感觉太水了。。。
首先肯定是要按照l对所有的数进行排序,比如说我们当前已经有tot个人确定参加了,那么剩下的我们
还要贪心的进行选择。选择满足l<=tot&&r>=tot中的r最小的那个人,很明显,只有这样选择对后来人的
影响才是最小的。对整体才是最优的。
用优先队列维护的代码:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> #include <set> #include <vector> using namespace std; const int maxn = 1e5+10; struct nod{ int l,r,id; bool operator < (const struct nod & tmp)const{ return r > tmp.r; } }p[maxn]; int ans[maxn]; bool vis[maxn]; bool cmp(const struct nod &p1,const struct nod &p2){ if(p1.l==p2.l) return p1.r<p2.r; return p1.l<p2.l; } int main() { int t,n; scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d",&p[i].l); p[i].id=i; } for(int i=1;i<=n;i++){ scanf("%d",&p[i].r); } sort(p+1,p+n+1,cmp); int tot=0,i=1,id=0; priority_queue<nod>Q; while(1){ while(p[i].l<=tot&&i<=n) Q.push(p[i]),i++; while(!Q.empty()){ nod tmp = Q.top(); if(tmp.r>=tot) break; ans[++id]=tmp.id; Q.pop(); } if(Q.empty()) break; else{ ans[++id] = Q.top().id; tot++; Q.pop(); } } while(i<=n) ans[i]=p[i].id,i++; printf("%d\n",tot); for(int i=1;i<n;i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
用set维护的代码:
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <queue> #include <set> using namespace std; const int maxn = 1e5+10; struct nod { int l ,r ,id ; bool operator < (const struct nod &tmp) const { if(l == tmp.l) return r < tmp.r ; return l<tmp.l ; } } p[maxn]; int ans[maxn]; bool vis[maxn]; set<pair<int,int > >st; set<pair<int,int > >::iterator it; int main() { int t,n; scanf("%d",&t); memset(vis,0,sizeof(vis)); while(t--) { scanf("%d",&n); for(int i=1; i<=n; i++) { scanf("%d",&p[i].l); p[i].id=i; } for(int i=1; i<=n; i++) { scanf("%d",&p[i].r); } sort(p+1,p+1+n); //memset(vis,0,sizeof(vis)); int tot=0,i=1; st.clear(); while(true) { while(tot>=p[i].l&&i<=n) st.insert(make_pair(p[i].r,p[i].id)),i++; if(st.size()==0) break; while(st.size()) { it = st.begin(); if(it->first >= tot) break; st.erase(st.begin()); } if(st.size()) { it = st.begin(); ans[++tot] = it->second; vis[it->second]=1; st.erase(st.begin()); } } printf("%d\n",tot); for(int i=1; i<=n; i++) { if(!vis[i]) ans[++tot]=i; else vis[i]=0; } for(int i=1; i<n; i++) printf("%d ",ans[i]); printf("%d\n",ans[n]); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-10-15 12:28:53