贪心+优先队列之更改优先级-hdu1896

题目描述:

题目理解:

  Sempr从位置0往前走,一路上他会遇到石子,如果这颗石子是他遇到的第奇数颗石子,那么他就把石子往前扔出去,如果他遇到的是第偶数颗石子,他会把它留在原地。需要注意的是,Sempr前面扔出去的石子,会继续作为后续会遇到的石子。如果在一个位置上有多颗石子,那么选出扔的最远的那颗石子扔出去。

  比如说第一个测试案例:Sempr在位置1遇到了第一颗石子,他将石子扔到了1+5=6的位置上。Sempr继续往前走,在位置2上遇到第二颗石子,他将其留在原地,并且继续往前走。当Sempr走到位置6时,他遇到了第三颗石子(这颗石子是由位置1的第一颗石子扔到这儿的),他将这颗石子扔到了6+5=11的位置上,并继续往前走。当Sempr走到位置11时,他遇到第四颗石子,他将其留在原地。至此,该测试案例中的石子就扔完了。所以最终的结果为11。

这道题由于运用到了优先队列,并且在同一个位置有多颗石子时需要更改队列的优先级,所以自己去了解了一下关于优先级修改的相关操作。

C/C++对bool operator < (const p &a)const的认识:http://www.cnblogs.com/ECJTUACM-873284962/p/6771262.html

结构体内嵌比较函数:http://www.cnblogs.com/ZERO-/p/9347296.html

代码分析:

#include <iostream>
#include <queue>
#include <cstdio>
using namespace std;
struct stone
{
    int d;
    int w;
    bool operator <(const stone &a)const//operator为C++里面的重载函数;括号中的const表示参数a对象不会被修改,最后的const表明调用函数对象不会被修改!
    {
        if(a.d==d)//如果石子的位置与队列中其他石子的位置一样
            return a.w<w;//在优先队列中,排序方式与sort函数相反,即默认的排序方式是a.w>w,当前对象的w如果大于其他元素的w(即a.w),那么w的优先级更高
        return a.d<d;//否则,位置靠前的优先级高
    }
}z;
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        priority_queue<stone>q;
        int n;
        scanf("%d",&n);
        while(n--)
        {
            scanf("%d %d",&z.d,&z.w);
            q.push(z);
        }
        int i=1;
        while(i)
        {
            if(i%2==1)//如果遇到的石头为第奇数颗,扔出去,并将该石子存入队列
            {
                z=q.top();
                q.pop();
                z.d+=z.w;
                q.push(z);
                if(q.size()==1)//如果队列中只还剩下1个元素,取出来后退出。
                {
                    printf("%d\n",q.top().d);
                    break;
                }
            }
            else//如果遇到的石头为第偶数颗,不理它
            {
                q.pop();
            }
            i++;
        }
    }
    return 0;

}

原文地址:https://www.cnblogs.com/LJHAHA/p/10012776.html

时间: 2025-01-18 08:26:18

贪心+优先队列之更改优先级-hdu1896的相关文章

poj3190Stall Reservations(贪心+优先队列)

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

LA 4254 Processor 处理器 【二分 贪心 优先队列】

题目链接: http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=21663 二分: 最大值最小的问题通过二分来求解.对处理器速度进行二分之后,问题就转化成了对于给定的处理速度,问处理器是否可以将这些问题处理完. 贪心: 一个贪心的思路就是每个时刻应该尽量 做可以做的任务中,结束时间最早的那个,这样最起码不会使结果更糟.这样就可以枚举每个单位时间,然后去找可以做的并且结束时间最早的那个去做,直到用完这一单位时间或者无任务可做为止.

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