HDU5630 Hiking(贪心+优先队列)

题目链接:传送门

题意:

邀请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

HDU5630 Hiking(贪心+优先队列)的相关文章

poj3190Stall Reservations(贪心+优先队列)

题目链接: 啊哈哈,点我点我 思路: 首先根据挤奶时间的先后顺序排序...然后将第一头牛加入优先队列..然后就是加入优先队列的牛应该根据越早结束挤奶那么优先级更高,如果时间结束点相等,那么开始时间早的优先级高... 然后从前向后枚举.如果碰到有牛的挤奶时间的开始值大于优先队列的首部的结束值,那么说明这两头牛可以一起公用一个挤奶房..然后从优先队列中删除这头牛..那么这个问题就得到解决了... 题目: Language: Default Stall Reservations Time Limit:

poj 2431 Expedition (贪心+优先队列)

Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6890   Accepted: 2065 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to

BZOJ 2151 种树 贪心+优先队列+HASH

题意:链接 方法:贪心+优先队列 解析: 首先裸上贪最大的肯定不对. DP可行么?可行,两个数组一个记录选一个记录不选好像差不多n^2? 不过还是想想贪心. 贪最大的为什么不对? 因为有可能它旁边的两个加起来比它更优越? 所以能否找到一点关系呢? 既然话都说到这了,两个加起来可能更优越. 所以我们在选了最大的之后是否应该回推一个值呢?代表选旁边俩. 我们发现选旁边俩是两个单位,选一个是一个单位,如果我们推回去某个值后这个值相当于对应删去一个单位选两个单位,即增加一个单位,这显然不会影响最终我们选

POJ1456Supermarket(贪心+优先队列)

Supermarket Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 9103   Accepted: 3891 Description A supermarket has a set Prod of products on sale. It earns a profit px for each product x∈Prod sold by a deadline dx that is measured as an int

[POJ1456]Supermarket(贪心 + 优先队列 || 并查集)

传送门 1.贪心 + 优先队列 按照时间排序从前往后 很简单不多说 ——代码 1 #include <queue> 2 #include <cstdio> 3 #include <iostream> 4 #include <algorithm> 5 #define N 10001 6 7 int n, t, ans; 8 std::priority_queue <int, std::vector <int>, std::greater &l

POJ 3190 Stall Reservations(贪心+优先队列优化)

Description Oh those picky N (1 <= N <= 50,000) cows! They are so picky that each one will only be milked over some precise time interval A..B (1 <= A <= B <= 1,000,000), which includes both times A and B. Obviously, FJ must create a reserv

hihoCoder 1309:任务分配 贪心 优先队列

#1309 : 任务分配 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定 N 项任务的起至时间( S1, E1 ), ( S2, E2 ), ..., ( SN, EN ), 计算最少需要多少台机器才能按时完成所有任务. 同一时间一台机器上最多进行一项任务,并且一项任务必须从头到尾保持在一台机器上进行.任务切换不需要时间. 输入 第一行一个整数 N,(1 ≤ N ≤ 100000),表示任务的数目. 以下 N 行每行两个整数 Si, Ei,(0 ≤ Si < 

Codeforces Round #FF/#255 D DZY Loves Modification --贪心+优先队列

题意:给你一个矩阵,每次选某一行或者某一列,得到的价值为那一行或列的和,然后该行每个元素减去p.问连续取k次能得到的最大总价值为多少. 解法: 如果p=0,即永远不减数,那么最优肯定是取每行或每列那个最大的取k次,所以最优解由此推出. 如果不管p,先拿,最后再减去那些行列交叉点,因为每个点的值只能取一次,而交叉点的值被加了两次,所以要减掉1次,如果取行A次,取列B次,那么最后答案为: res = dp1[A] + dp2[B] - B*(k-A)*p,可以细细体会一下后面那部分. 其中: dp1

POJ 1862 Stripies 贪心+优先队列

http://poj.org/problem?id=1862 题目大意: 有一种生物能两两合并,合并之前的重量分别为m1和m2,合并之后变为2*sqrt(m1*m2),现在给定n个这样的生物,求合并成一个的最小重量 思路: m1+m2 >=  2*sqrt(m1*m2) 所以每次取大的去合并,能变小. 直接优先队列就可以啦. #include<cstdio> #include<cmath> #include<queue> using namespace std;

UVA 1422 - Processor (二分+贪心+优先队列)

先对开始时间进行排序,在利用优先队列是结束时间早点先出队: 因为时间只有20000,我们可以去枚举每个单位时间,看要给分配给那个任务, 如果某个时间队列中还有结束时间大于枚举的时间,就跳出判断是在mid的右边. #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> #include<stdlib.h> #include<math.h> #