zoukankan      html  css  js  c++  java
  • [Luogu]小Z的AK计划

    Description

    Luogu2107

    Solution

    一开始打了一个60分的暴力DP,结果一分都没得……本地调了好久才发现是没开long long

    由于我的DP方程没有任何性质,就是一个01背包,所以就没啥可优化的了。

    这个题的正解其实不是DP,而是贪心……由于是单向的走,在每个位置选用时少的机房AK总是好的,这也就等价于不在用时多的机房AK,所以开个堆存一下AK了那些机房,超时了就把时间最长的机房去掉就行了。

    Code

    DP:

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    
    typedef long long LL;
    const int N = 1e5 + 10;
    
    LL f[N];
    LL n, m;
    struct node {
        LL t, x;
        bool operator<(const node& a) const { return x < a.x; }
    } a[N];
    
    int main() {
        scanf("%lld%lld", &n, &m);
        for (int i = 1; i <= n; ++i) scanf("%lld%lld", &a[i].x, &a[i].t);
        std::sort(a+1, a+n+1);
        memset(f, 0x3f, sizeof f);
        f[0] = 0;
        LL ans = 0;
        for (int i = 1; i <= n; ++i) {
            for (int j = i; j; --j) {
                f[j] = std::min(f[j] + a[i].x - a[i-1].x, f[j-1] + a[i].x - a[i-1].x + a[i].t);
                if (f[j] <= m) ans = std::max(ans, 1ll*j);
            }
            f[0] += a[i].x - a[i-1].x;
        }
        printf("%lld
    ", ans);
        return 0;
    }
    

    贪心:

    #include <cstdio>
    #include <algorithm>
    #include <queue>
    
    typedef long long LL;
    const int N = 100000 + 10;
    
    int n;
    LL m;
    struct node {
        LL x, t;
        bool operator<(const node& b) const { return t < b.t; }
    } a[N];
    std::priority_queue<node> q;
    
    bool cmp(const node& a, const node& b) { return a.x < b.x; }
    
    int main() {
        scanf("%d%lld", &n, &m);
        for (int i = 1; i <= n; ++i) {
            scanf("%lld%lld", &a[i].x, &a[i].t);
            if (a[i].x > m || a[i].t > m) { --i; --n; }
        }
        std::sort(a+1, a+n+1, cmp);
        int tmp = 0, ans = 0; LL t = 0;
        for (int i = 1; i <= n; ++i) {
            t += a[i].t;
            tmp++;
            q.push(a[i]);
            while (!q.empty() && t + a[i].x > m) {
                tmp--;
                t -= q.top().t;
                q.pop();
            }
            if (t + a[i].x <= m) ans = std::max(ans, tmp);
        }
        printf("%d
    ", ans);
    }
    

    Note

    • long longlong longlong long,这个题不开long long一分都没有,想象一下NOIp如果如此的话,我大概就gg了。
    • 花费或价值相同的背包问题可以贪心啊!!!
  • 相关阅读:
    31天重构学习笔记18. 使用条件判断代替异常
    31天重构学习笔记12. 分解依赖
    31天重构学习笔记2. 移动方法
    .NET 技术社区谈之中文篇
    31天重构学习笔记10. 提取方法
    31天重构学习笔记14. 分离职责
    31天重构学习笔记20. 提取子类
    31天重构学习笔记16. 封装条件
    31天重构学习笔记17. 提取父类
    .NET 技术社区谈之英文篇
  • 原文地址:https://www.cnblogs.com/wyxwyx/p/lg2107.html
Copyright © 2011-2022 走看看