您的位置:首页 > 其它

[贪心+优先队列] hdu5360多校联合 第六场 Hiking

2015-08-07 10:15 417 查看
http://acm.hdu.edu.cn/showproblem.php?pid=5360

贪心的思路还是比较好想的,每次选择cur(已经邀请成功的人数)所在的区间中右端点最小的(因为右端点大的在后面可以邀请成功的几率大),然后很自然的想到可以用一个优先队列来维护这些区间,只要每次把左端点小于等于cur的区间放到优先队列中即可。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<string>
#include<iostream>
#include<queue>
using namespace std;
int n;
struct node
{
int l,r,id;
friend bool operator < (node a, node b)
{
return a.r>b.r;
}
}
a[100010];
int used[100010];
bool cmp(node a, node b)
{
return a.l<b.l;
}
int main()
{
int T;
scanf("%d",&T);

while(T--)
{
scanf("%d",&n);
for(int i=0; i<n; i++)
scanf("%d",&a[i].l);
for(int i=0; i<n; i++)
{
scanf("%d",&a[i].r);
a[i].id=i+1;
}
sort(a,a+n,cmp);
//  for(int i = 0;i<n;i++)
//      printf("i = %d, L = %d, R = %d\n",i,a[i].l,a[i].r);
priority_queue<node> que;

vector<int> people;
memset(used,0,sizeof used);

int ans=0;
int tot=0;
while(tot<n || que.size())
{
while(tot<n && a[tot].l<=ans)
{
que.push(a[tot]);
tot++;
}
while(que.size() && que.top().r < ans) que.pop();
if(que.empty()) break;
ans++;
people.push_back(que.top().id);
used[que.top().id]=1;
que.pop();
}
printf("%d\n",ans);

int num=1;
for(int i=0; i<people.size(); i++)
{
printf("%d%c",people[i],num==n?'\n':' ');
num++;
}
for(int i=1; i<=n; i++)
{
if(used[i]==0)
{
printf("%d%c",i,num==n?'\n':' ');
num++;
}
}
}
return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: