• Codeforces 1257D Yet Another Monster Killing Problem(二分+贪心)


    题目链接

    题目大意

      给n个数a,之后再给m组数b,b中每组数第一个数如果大于a中的某个数,则可以删除这个数,第二个数代表这个数一次能删除几个连续的数。a中的每个数只能按顺序被删除,问最小删除次数。

    解题思路

      首先先把b中的数按第一个数排序,然后用一个数组记录大于等于这个数的最大次数,如果次数用完了或者出现了更大的数,就二分找一个更大的数,然后更新次数,依次贪心即可。

    代码

    const int maxn = 2e5+10;
    const int maxm = 2e2+10;
    struct IF {
        int x, cnt;
    } info[maxn], arr[maxn]; int post[maxn];
    int main() {
        int t; cin >> t;
        while(t--) {
            int n; cin >> n;
            for (int i = 1; i<=n; ++i) scanf("%d", &arr[i].x); 
            int m; cin >> m;
            for (int i = 1; i<=m; ++i) scanf("%d%d", &info[i].x, &info[i].cnt);
            sort(info+1, info+m+1, [](IF a, IF b) {return a.x<b.x;});
            post[m+1] = 0;
            for (int i = m; i>=1; --i) post[i] = max(post[i+1], info[i].cnt);
            int damage = 0, cnt = 0, days = 0, ans = 0;
            for (int i = 1; i<=n; ++i) {
                ++cnt;
                if (days<cnt || damage<arr[i].x) {
                    int p = lower_bound(info+1, info+m+1, arr[i], [](const IF &a, const IF &b) {return a.x<b.x;})-info;
                    if (p==m+1) {
                        cout << -1 << endl; goto out;
                    }
                    if (days<cnt) ++ans, cnt = 1;
                    days = post[p], damage = info[p].x;
                    if (days<cnt) ++ans, cnt = 1;
                }
            }
            cout << ans << endl;
            out:;
        }
        return 0;   
    }
    
  • 相关阅读:
    缓存穿透、缓存并发、缓存失效
    改善Java文档的理由、建议和技巧
    如何用消息系统避免分布式事务?
    灰度发布
    REFLECTION(反射)INTROSPECTION(内省、内观)
    常规版本如果新增字段或新增状态如何正确处理
    Git库管理规范
    .net 创建文件夹
    HTTP消息头
    C#读取指定文件夹中的所有文件
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/13589738.html
Copyright © 2020-2023  润新知