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;
    }
  • 相关阅读:
    async await 了解
    vi 命令
    mysql 相关操作
    mac下配置python的虚拟环境virtualenv和虚拟环境管理包virtualenvwrapper
    ip 域名 和端口号
    脱离 flask 上下文,使用 jinja2 来动态渲染模板
    使用 vue-cli 3.0 创建项目
    p 标签和 span 标签
    el-table 更改表格行高和列髋
    使用 axios 传参问题
  • 原文地址:https://www.cnblogs.com/zzzzzzy/p/12197694.html
Copyright © 2011-2022 走看看