• Solution 「CF 808E」Selling Souvenirs


    \(\mathscr{Description}\)

      Link.

      01 背包。

      物品种类 \(n\le10^5\),背包容量 \(m\le3\times10^5\),单个物品体积 \(w\in\{1,2,3\}\),价值 \(c\le10^9\)

    \(\mathscr{Solution}\)

      模拟赛 T3(不是说这题)什么降智选择结构,我直接开摆。

      Motivation: 只有两种体积,我会 two-pointers。

      构造一发,把 \(w=1\) 的物品转化成 \(w=2\) 的物品:枚举 \(w=1\) 选择的奇偶性,若为奇,最大者必选,其余两两打包;若为偶,直接两两打包。化归到 \(w=\{2,3\}\) 的情况,算上排序的复杂度就能 \(\mathcal O(n\log n)\) 做了。

      騞然已解,如土委地。(

      这种拆物品、组合物品的构造 trick 还挺厉害的,要多留意一下√

    \(\mathcal {Code}\)

    /*+Rainybunny+*/
    
    #include <bits/stdc++.h>
    
    #define rep(i, l, r) for (int i = l, rep##i = r; i <= rep##i; ++i)
    #define per(i, r, l) for (int i = r, per##i = l; i >= per##i; --i)
    
    typedef long long LL;
    
    inline char fgc() {
        static char buf[1 << 17], *p = buf, *q = buf;
        return p == q && (q = buf + fread(p = buf, 1, 1 << 17, stdin), p == q) ?
          EOF : *p++;
    }
    
    template <typename Tp = int>
    inline Tp rint() {
        Tp x = 0, s = fgc(), f = 1;
        for (; s < '0' || '9' < s; s = fgc()) f = s == '-' ? -f : f;
        for (; '0' <= s && s <= '9'; s = fgc()) x = x * 10 + (s ^ '0');
        return x * f;
    }
    
    const int MAXN = 1e5;
    int n, m;
    std::vector<int> buc[3];
    
    inline LL solve() {
        std::sort(buc[1].begin(), buc[1].end(), std::greater<int>());
        LL ret = 0, sum = 0;
        int p = 0, q = 0;
        while (p < buc[2].size() && (p + 1) * 3 <= m) sum += buc[2][p++];
        while (q < buc[1].size() && (q + 1) * 2 + p * 3 <= m)
            sum += buc[1][q++];
        ret = std::max(ret, sum);
        while (~--p) {
            sum -= buc[2][p];
            while (q < buc[1].size() && (q + 1) * 2 + p * 3 <= m)
                sum += buc[1][q++];
            ret = std::max(ret, sum);
        }
        return ret;
    }
    
    int main() {
        n = rint(), m = rint();
        rep (i, 1, n) {
            int w = rint(), c = rint();
            buc[w - 1].push_back(c);
        }
    
        std::sort(buc[0].begin(), buc[0].end(), std::greater<int>());
        std::sort(buc[2].begin(), buc[2].end(), std::greater<int>());
        
        auto tmp(buc[1]);
        for (int i = 0; i + 1 < buc[0].size(); i += 2) {
            buc[1].push_back(buc[0][i] + buc[0][i + 1]);
        }
        LL ans = solve();
    
        if (buc[0].size()) {
            buc[1] = tmp;
            for (int i = 1; i + 1 < buc[0].size(); i += 2) {
                buc[1].push_back(buc[0][i] + buc[0][i + 1]);
            }
            --m, ans = std::max(ans, solve() + buc[0][0]);
        }
        printf("%lld\n", ans);
        return 0;
    }
    
    
  • 相关阅读:
    虚拟机VirtualBox 共享挂载问题:mount: /mnt/xxx: wrong fs type, bad option, bad superblock on xxx
    git 设置和取消代理
    (转载)数据库连接池到底应该设多大?这篇文章可能会颠覆你的认知
    关于golang中IO相关的Buffer类浅析
    (转)golang获取当前时间、时间戳和时间字符串及它们之间的相互转换
    FFmpeg常用命令
    go cmd nohup 的坑
    Nginx配置详解(转)
    记录一次go性能调试的过程
    github徽标引入
  • 原文地址:https://www.cnblogs.com/rainybunny/p/16051574.html
Copyright © 2020-2023  润新知