zoukankan      html  css  js  c++  java
  • Luogu 3537 [POI2012]SZA-Cloakroom

    背包。

    首先考虑将所有询问离线按照$m$从小到大排序,然后把所有物品按照$a$从小到大排序,对于每一个询问不断加入物品。

    设$f_i$表示在组成容量为$i$的背包的所有方案中$b$最小的一个物品的最大$b$是多少,对于物品$i$和容量$j$,有转移$f_j = max(f_j, min(f_{j - c_i}, b_i))$。

    时间复杂度$O(MaxK * n)$,感觉非常紧,实际上还行。

    Code:

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 1005;
    const int M = 1e6 + 5;
    const int Maxm = 1e5;
    const int inf = 1 << 30;
    
    int n, qn, f[Maxm + 5];
    bool ans[M];
    
    struct Item {
        int sa, sb, sc;
        
        friend bool operator < (const Item &x, const Item &y) {
            return x.sa < y.sa;
        }
        
    } a[N];
    
    struct Querys {
        int m, k, s, id;
        
        friend bool operator < (const Querys &x, const Querys &y) {
            return x.m < y.m;    
        }
        
    } q[M];
    
    inline void read(int &X) {
        X = 0; char ch = 0; int op = 1;
        for(; ch > '9' || ch < '0'; ch = getchar())
            if(ch == '-') op = -1;
        for(; ch >= '0' && ch <= '9'; ch = getchar())
            X = (X << 3) + (X << 1) + ch - 48;
        X *= op;
    }
    
    inline int min(int x, int y) {
        return x > y ? y : x;
    }
    
    inline void chkMax(int &x, int y) {
        if(y > x) x = y;
    }
    
    int main() {
        read(n);
        for(int i = 1; i <= n; i++) 
            read(a[i].sc), read(a[i].sa), read(a[i].sb);
        read(qn);
        for(int i = 1; i <= qn; i++) {
            read(q[i].m), read(q[i].k), read(q[i].s);
            q[i].id = i;
        }
        
        sort(a + 1, a + 1 + n), sort(q + 1, q + 1 + qn);
        f[0] = inf;
        for(int j = 1, i = 1; i <= qn; i++) {
            for(; j <= n && a[j].sa <= q[i].m; ++j) {
                for(int k = Maxm; k >= a[j].sc; k--)
                    chkMax(f[k], min(f[k - a[j].sc], a[j].sb));
            }
            if(f[q[i].k] > q[i].m + q[i].s) ans[q[i].id] = 1;
        }
        
        for(int i = 1; i <= qn; i++)
            puts(ans[i] ? "TAK" : "NIE");
        
        return 0;
    }  
    View Code
  • 相关阅读:
    调试
    node笔记汇总
    移动端布局
    css 易错点总结
    Angular笔记
    CANVAS笔记
    http笔记汇总
    各种环境搭建 软件安装等等 参考网址收录
    js中同步异步,任务队列
    node.js之fs模块
  • 原文地址:https://www.cnblogs.com/CzxingcHen/p/9896045.html
Copyright © 2011-2022 走看看