模拟 - hdu5360 Hiking

本文介绍了一种基于排序和优先队列的算法,用于解决邀请特定人数的郊游参与者问题,使得邀请到的人数最多。通过按人数限制排序和使用优先队列来跟踪符合条件的参与者,实现最优邀请策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=5360


题意:

某君要邀请n个人去郊游,每个人都有奇特的要求,对于第i个人,只有当前答应去郊游的人数cur满足MIN[i]<=cur<=MAX[i],他才会答应参加,并且参加后不会反悔,问最多能邀请到多少人去郊游,并给出任意满足题意邀请序列


思路:

先依据所有人min进行排序,当邀请人数为cur时,把数组里所有min等于cur的人放入优先队列,邀请队列中max最小,且max<=cur的那个人


代码:

#include<stdio.h>
#include<iostream>
#include<string>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<functional>
#pragma comment(linker, "/STACK:102400000,102400000")//C++
using namespace std;

const double PI = 3.141592653589793238462643383279502884197169399;
const int MAXINT = 0x7fffffff;
const int MAXSIZE = 100000 + 5;
const long long INF = 0x7FFFFFFFFFFFFFFF;

struct node{
    int num;
    int l,r;
};

bool operator <(const node&p1, const node&p2){
	return p1.r>p2.r;
}


void quick_sort(node arr[],int l,int r){
    int i=l,j=r;
    int x=arr[(l+r)>>1].l;
    while (i<=j){
        while (arr[i].l<x) i++;
        while (arr[j].l>x) j--;
        if (i<=j){
            swap(arr[i],arr[j]);
            i++;
            j--;
        }
    }
    if (i<r) quick_sort(arr,i,r);
    if (l<j) quick_sort(arr,l,j);
}

node arr[MAXSIZE];
vector<int> ans;
priority_queue<node> Q;

int main(){
    int total;
    cin>>total;
    while (total--){
        int n;
        scanf("%d",&n);
        for (int i=0;i<n;++i){
            scanf("%d",&arr[i].l);
            arr[i].num = i+1;
        }
        for (int i=0;i<n;++i){
            scanf("%d",&arr[i].r);
        }
        quick_sort(arr,0,n-1);
        int cur=0;
        int k=0;

        ans.clear();
        while (!Q.empty()) Q.pop();

        while (arr[k].l == 0) {
            Q.push(arr[k]);
            k++;
        }

        while (!Q.empty()){
            while (!Q.empty()){
                if (Q.top().r<cur) {
                    ans.push_back(Q.top().num);
                    Q.pop();
                }
                else break;
            }
            if (!Q.empty()){
                ans.push_back(Q.top().num);
                Q.pop();
                cur++;
                //cout<<cur<<" "<<ans[ans.size()-1]<<endl;
            }
            while (arr[k].l == cur) {
                Q.push(arr[k]);
                k++;
            }
        }
        while (k<=n-1) {ans.push_back(arr[k].num);k++;}

        printf("%d\n",cur);

        for (int i=0;i<ans.size()-1;++i){
            printf("%d ",ans[i]);
        }
        printf("%d\n",ans[ans.size()-1]);
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值