标签:
4 8 4 1 3 2 2 1 0 3 5 3 6 4 2 1 7 6 8 3 3 2 0 5 0 3 6 4 5 2 7 7 6 7 6 8 2 2 3 3 3 0 0 2 7 4 3 6 3 2 2 5 8 5 6 5 3 3 1 2 4 6 7 7 6 5 4 3 5
7 1 7 6 5 2 4 3 8 8 4 6 3 1 2 5 8 7 7 3 6 7 1 5 2 8 4 0 1 2 3 4 5 6 7 8
题意:现在有n个人等待邀请,但是第i个人可以被邀请的要求是邀请他的时候,已经邀请的人不少于ai个且不多于bi个。当一个人被邀请之后不会反悔离开。
求最多邀请的人数,以及邀请的顺序(邀请了不来也得写上)
很简单很明确的一个贪心。
首先按每个人至少的要求排序。每次把当前达到最少要求的人取出来放入优先队列,然后每次抉择的时候按至多要求的人数最小的开始邀请即可。
下面贴代码。
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <map> #include <queue> #include <vector> #include <iostream> #include <algorithm> #define moo 1000000007//10^9+7 #define PI acos(-1.0) #define eps 1e-5 using namespace std; struct People { int Min,Max,id; }peo[100000+10]; bool operator <(People x,People y) { return x.Max>y.Max; }//优先队列内以至多值从小到大排序 bool cmp(People x,People y) { return x.Min<y.Min; } priority_queue<People>Q; vector<int>ans; int main() { int T; cin>>T; while(T--) { while(!Q.empty()) Q.pop(); ans.clear(); int n; scanf("%d",&n); for(int i=1;i<=n;peo[i].id=i,i++) scanf("%d",&peo[i].Min); for(int i=1;i<=n;i++) scanf("%d",&peo[i].Max); sort(peo+1,peo+n+1,cmp); int cnt=0,use=1;//cnt存已经成功邀请的人,use未达到最小值的当前的人 do { if(!Q.empty()) { if(Q.top().Max>=cnt) cnt++; ans.push_back(Q.top().id); Q.pop(); }//首先判断当前队列首的人会不会已经超过了上限, for(;use<=n;use++)//判断当前人的最小值是否被满足,如果满足,就加入优先队列 if(peo[use].Min<=cnt) Q.push(peo[use]); else break; }while(!Q.empty());//当队列为空说明不会有人再满足最小值了 int flag=0; cout<<cnt<<endl; for(int i=0;i<ans.size();flag=1,i++)//按顺序输出满足过最小值的人 printf(flag==0?"%d":" %d",ans[i]); for(;use<=n;flag=1,use++)//将未满足最小值的人输出 printf(flag==0?"%d":" %d",peo[use].id); printf("\n"); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/zip_fan/article/details/47340287