【JZOJ 3487】剑与魔法【贪心】【堆】

版权声明:若希望转载,在评论里直接说明即可,谢谢! https://blog.csdn.net/SSL_ZYC/article/details/82529413

题目大意:

题目链接:https://jzoj.net/senior/#main/show/3487
n 条指令。每个指令有以下两种格式。

  • c   x :若执行该指令,则可以获得 x 价值。
  • e   x :在接到这条指令之前不可以执行超过或等于 x c 指令。

在忽略最后一个 e 指令的前提下求最大价值。


思路:

居然是贪心。。。
对于每一个 e 指令,我们不能执行超过 x c 指令,那么很明显,肯定是要尽量多执行 c 指令并且执行价值较大的指令
那么就将读入到的指令放入一个小根堆里,每次当执行的 c 指令超过 x 条时,就删除小根堆的最小元素,这样就可以保证所得到的价值最大。
然后对于 c 指令就直接将元素插入堆即可。


代码:

#include <cstdio>
#include <queue>
#include <iostream>
using namespace std;

int n,a[200100],sum;
char c;
priority_queue<int> q;

int main()
{
    scanf("%d",&n);
    for (int i=1;i<n;i++)
    {
        cin>>c>>a[i];
        if (c=='c') q.push(-a[i]);  
        //STL原本是大根堆,但是去成相反数之后原本更大的数就会更小,就达到了小根堆的目的。
        else
         while (q.size()>=a[i]) q.pop();  //e指令,留下最大的x-1个元素
    }
    cin>>c>>a[n];
    if (q.size()<a[n])  //判断最后是否有x个元素
    {
        printf("-1");
        return 0;
    }
    while (q.size())
    {
        sum-=q.top();  //由于取了相反数,所以最后原本是相加,就变成了相减
        q.pop(); 
    }
    printf("%d\n",sum);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_ZYC/article/details/82529413
今日推荐