hdu5360Hiking 贪心

来源:互联网 发布:软通动力java工资 编辑:程序博客网 时间:2024/05/16 15:22
//n个人接受邀请的条件是已经接受邀请的人数区间在l[i] , r[i] //问怎样设置邀请顺序能使得接受邀请的人数最多//先对其对从小到大排序//然后维护一个set,set中存入左边满足条件的所有人,//然后贪心策略是每次取左边满足条件的右边最小的人//每次多邀请一个人后删除右边不满足条件的人#include<cstdio>#include<cstring>#include<iostream>#include<set>#include<algorithm>using namespace std ;const int maxn = 100010 ;int a[maxn] ;   int t  ;int n ;int vis[maxn] ;struct node{    int l ,r ,id ;    bool operator < (const struct node tmp) const    {        if(l == tmp.l)        return r < tmp.r ;        return l<tmp.l ;    }} p[maxn];multiset<pair<int, int> > s ;multiset<pair<int , int> >::iterator it ;int main(){   // freopen("in.txt" ,"r" , stdin) ;    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) ;        int ans = 0 ;        int i = 1;        s.clear() ;        while(1)        {            while(ans >= p[i].l && i <= n)            {                s.insert(make_pair(p[i].r , p[i].id)) ;                i++;            }            if(!s.size())break;            while(s.size())            {                it = s.begin() ;                if(it->first >= ans)                break;                s.erase(s.begin()) ;            }            if(s.size())            {                it = s.begin();                a[++ans] = it->second ;                vis[it->second] = 1;                s.erase(s.begin()) ;            }        }        printf("%d\n"  ,ans) ;        for(int i = 1;i <= n;i++)        if(!vis[i])        a[++ans] = i ;        else vis[i] = 0 ;        for(int i = 1;i <= ans ;i++)        printf("%d%c" , a[i] , i == ans ? '\n':' ') ;    }    return 0 ;}
0 0