zoukankan      html  css  js  c++  java
  • Codeforces Round #608 (Div. 2)

    题意:你起初有一支军队,有$k$个士兵,现在有$n$座城堡,你若想占领第$i$座城堡,至少得有$a[i]$个士兵才能占领$($占领后士兵不会减少$)$,占领了第$i$座城堡后,你将得到$b[i]$个士兵,然后你有两种方式防御你占领的城堡:

    • 在你占领第$i$个城堡后留下一个士兵防御第$i$个城堡
    • 有$m$个传送门,能从$u_{i}$传送到$v_{i}(u_{i}>v_{i})$,你可以在占领完第$u_{i}$座城堡后再派一个士兵去防御第$v_{i}$个城堡

    如果你防御了第$i$座城堡,你能得到$c[i]$的成就值,现在问你,如果你能占领全部的城堡,你能获得的最大的成就值是多少,若不能占领全部的城堡, 输出$-1$。

    思路:对于每一座城堡,如果它能在多个地方被防御,那么肯定选择最远能够被防御的地方,所以预处理出$to[i][j]$表示第$to[i][j]$个城堡最远能被防御的地方是第$i$个城堡,根据贪心的思想,我们对于城堡$i$,应该将城堡$i$能够到达的城堡$to[i][j]$全部进行防御,防御时按照成就值从高到低依次防御,当没有士兵进行防御时,如果当前需要防御的城堡的成就值大于你已经防御的城堡里面成就值的最小值,则应该放弃那个成就值最小的城堡,来防御当前的城堡,当发现自己的士兵不够占领某个城堡时,贪心放弃那些成就低的城堡,利用优先队列,每次放弃城堡时取出队头即可。

    #include <iostream>
    #include <algorithm>
    #include <cstdio>
    #include <queue>
    #include <vector>
     
    using namespace std;
     
    const int N = 5010;
     
    struct node {
        int a, b, c;
    };
     
    int n, m, k, pos[N];
    vector<int> to[N];
    node p[N];
    priority_queue< int, vector<int>, greater<int> > q;
     
    void init()
    {
        for (int i = 1; i <= n; i++) pos[i] = i;
    }
     
    bool cmp(int a, int b)
    {
        return p[a].c > p[b].c;
    }
     
    int main()
    {
        scanf("%d%d%d", &n, &m, &k);
        init();
        for (int i = 1; i <= n; i++)
            scanf("%d%d%d", &p[i].a, &p[i].b, &p[i].c);
        for (int i = 1; i <= m; i++) {
            int u, v;
            scanf("%d%d", &u, &v);
            pos[v] = max(pos[v], u);
        }
        for (int i = 1; i <= n; i++) to[pos[i]].push_back(i);
        for (int i = 1; i <= n; i++) sort(to[i].begin(), to[i].end(), cmp);
        int res = 0, flag = 1;
        for (int i = 1; i <= n; i++) {
            if (p[i].a > k) {
                int dis = p[i].a - k;
                if (dis > q.size()) {
                    flag = 0; break;
                }
                while (dis--) {
                    int tp = q.top(); q.pop();
                    res -= tp, k++;
                }
            }
            k += p[i].b;
            for (int j = 0; j < (int)to[i].size(); j++) {
                int v = to[i][j];
                if (0 == p[v].c) continue;
                if (0 == k && !q.empty() && p[v].c > q.top()) {
                    int tp = q.top(); q.pop();
                    res -= tp, k++;
                }
                if (k > 0) res += p[v].c, q.push(p[v].c), k--;
            }
        }
        if (0 == flag) printf("-1
    ");
        else printf("%d
    ", res);
        return 0;
    }
  • 相关阅读:
    关于ViewPager、ViewFilpper、ViewFlow三种实现水平向滑动方式的比较
    php 使用curl模拟登录discuz以及模拟发帖
    php 使用curl模拟登录人人(校内)网
    PHP PDO函数库详解
    比CMD更强大的命令行WMIC
    强大的命令行工具wmic
    wmic 命令的一个汇总,功能很强大
    Oracle 11g default profile 默认启用密码过期180天 ORA-28001错误处理
    Oracle 11g密码过期问题解决方案
    SQLPlus 在连接时通常有四种方式
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12197694.html
Copyright © 2011-2022 走看看