首页 > 其他分享 >[ARC105C] Camels and Bridge 题解

[ARC105C] Camels and Bridge 题解

时间:2023-11-06 20:34:28浏览次数:28  
标签:ARC105C std le limits Bridge 题解 valueType 重物 max

题意

给定 \(N\) 个重物,其中第 \(i\) 个重物的重量为 \(w_i\)。现在要将其排成一排,可以任意指定相邻两个重物的距离。

同时给定 \(M\) 个限制,其中第 \(i\) 个限制为 \((l_i, v_i)\),表示要求不存在长度为 \(l_i\) 的线段,使得其包括的重物重量之和大于 \(v_i\)。

最小化重物间的最大距离或报告无解。

  • \(2 \le N \le 8\)
  • \(1 \le M \le 10^5\)
  • \(1 \le w_i, l_i, v_i \le 10^8\)

题解

首先,若 \(\max\limits_{i = 1}^{N} w > \min\limits_{i = 1}^{M} v_i\),那么一定无解,反之一定有解。下文中假设一定有解。

由于 \(N\) 的值很小,所以可以考虑枚举重物之间的排列顺序,然后依次计算 \(N!\) 种排列的最小化的最大距离。

考虑如何计算,不妨设 \(f_{i}\) 表示第 \(i\) 个重物到第一个重物的最小距离,那么有转移

\[f_{i} = \max\limits_{j = 1}^{i - 1} \left\{f_j + L\left(\sum\limits_{k = j}^{i}w_i\right)\right\} \]

其中 \(L(x)\) 表示一段总重量为 \(x\) 的线段的最短长度。

现在问题转化为了如何快速求出 \(L(x)\),发现 \(L(x)\) 可以表示为:

\[\max\limits_{1 \le i \le M \land v_i \le x} l_i \]

因此我们可以将所有限制按 \(v_i\) 的大小升序排序,那么求 \(L(x)\) 时只需要二分出最大的满足 \(v_i \le x\) 的 \(i\) 后查询前缀最大值即可。

时间复杂度 \(\mathcal{O}(N!N^2\log M + M \log M)\),空间复杂度 \(\mathcal{O}(N + M)\),可以通过。

Code

#include <bits/stdc++.h>

typedef long long valueType;
typedef std::vector<valueType> ValueVector;
typedef std::pair<valueType, valueType> ValuePair;
typedef std::vector<ValuePair> PairVector;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    std::cout.tie(nullptr);

    valueType N, M;

    std::cin >> N >> M;

    ValueVector W(N + 1, 0);

    for (valueType i = 1; i <= N; ++i)
        std::cin >> W[i];

    PairVector A(M + 1);

    for (valueType i = 1; i <= M; ++i)
        std::cin >> A[i].second >> A[i].first;

    {
        valueType maxW = std::numeric_limits<valueType>::min(), minV = std::numeric_limits<valueType>::max();

        for (valueType i = 1; i <= N; ++i)
            maxW = std::max(maxW, W[i]);

        for (valueType i = 1; i <= M; ++i)
            minV = std::min(minV, A[i].first);

        if (maxW > minV) {
            std::cout << -1 << std::endl;

            return 0;
        }
    }

    std::sort(A.begin() + 1, A.end());

    ValueVector max(M + 1, 0);

    for (valueType i = 1; i <= M; ++i)
        max[i] = std::max(max[i - 1], A[i].second);

    auto calc = [&](valueType sum) -> valueType {
        valueType l = 1, r = M, ans = 0;

        while (l <= r) {
            valueType mid = (l + r) / 2;

            if (A[mid].first < sum) {
                ans = mid;
                l = mid + 1;
            } else {
                r = mid - 1;
            }
        }

        return max[ans];
    };

    ValueVector P(N + 1, 0);

    std::iota(P.begin(), P.end(), 0);

    valueType ans = std::numeric_limits<valueType>::max();

    do {
        ValueVector F(N + 1, 0);

        F[0] = 0;
        for (valueType i = 1; i <= N; ++i) {
            F[i] = 0;

            valueType sum = W[P[i]];

            for (valueType j = i - 1; j >= 1; --j) {
                sum += W[P[j]];

                F[i] = std::max(F[i], F[j] + calc(sum));
            }
        }

        ans = std::min(ans, F[N]);
    } while (std::next_permutation(P.begin() + 1, P.end()));

    std::cout << ans << std::endl;
}

标签:ARC105C,std,le,limits,Bridge,题解,valueType,重物,max
From: https://www.cnblogs.com/User-Unauthorized/p/solution-ARC105C.html

相关文章

  • [ARC105D] Let's Play Nim 题解
    题意给定\(N\)个背包,其中第\(i\)个背包中有\(a_i\)个石子。同时还有\(N\)个盘子,初始时盘子中没有石子。两人轮流执行下列操作:若存在背包中还有石子,选择一个非空背包和盘子,将背包中的石子放入盘子中,注意这里对盘子没有要求;若不存在背包中还有石子,选择一个非空盘子,将盘......
  • 题解 LOJ3483【[USACO21FEB] Counting Graphs P】
    题解P7418【[USACO21FEB]CountingGraphsP】problemBessie有一个连通无向图\(G\)。\(G\)有\(N\)个编号为\(1\ldotsN\)的结点,以及\(M\)条边(\(1\leN\le10^2,N-1\leM\le\frac{N^2+N}{2}\))。\(G\)有可能包含自环(一个结点连到自身的边),但不包含重边(连接同一对结点......
  • Daleks' Invasion 题解
    Daleks'Invasion题目大意给定一张无向带权图,对于每条边求一个最大的\(x\),使得将这条边的边权修改为\(x\)后这条边能位于这张图的最小生成树上。思路分析没事干了就把之前写过的题拉出来水题解。我们先把原图的最小生成树求出来,考虑每条边\((u,v)\),分类讨论:如果这条边......
  • Groceries in Meteor Town 题解
    GroceriesinMeteorTown题目大意维护一颗带权树,支持以下操作:将\([l,r]\)内的点变为白色。将\([l,r]\)内的点变为黑色。查询点\(x\)到任意一个白色节点的简单路径上的最大值。思路分析没事干了把以前的题拿出来写题解。看到『简单路径上的最大值』的字样首......
  • Harvester 题解
    Harvester题目大意给定\(n\timesm\)的网格,每次可以选一行或一列,将这一行或一列上的数全部取走,最多可以取四次,问取走的数的和的最大值。思路分析没事干了把以前写过的题拿出来写题解。分类讨论题。在只能取四次的情况下一共只有这么几种可能:选四行:毫无疑问,行之间互不......
  • 大文件上传 问题解决三种方案
    最近遇见一个需要上传百兆大文件的需求,调研了七牛和腾讯云的切片分段上传功能,因此在此整理前端大文件上传相关功能的实现。在某些业务中,大文件上传是一个比较重要的交互场景,如上传入库比较大的Excel表格数据、上传影音文件等。如果文件体积比较大,或者网络条件不好时,上传的时间会......
  • vue视频直接播放rtsp流;vue视频延迟问题解决;webRTC占cpu太大卡死问题解决;解决webRTC播
    vue视频直接播放rtsp流;vue视频延迟问题解决;webRTC占cpu太大卡死问题解决;解决webRTC播放卡花屏问题::https://blog.csdn.net/killerdoubie/article/details/133884070......
  • 【洛谷 P1046】[NOIP2005 普及组] 陶陶摘苹果 题解(比较)
    [NOIP2005普及组]陶陶摘苹果题目描述陶陶家的院子里有一棵苹果树,每到秋天树上就会结出个苹果。苹果成熟的时候,陶陶就会跑去摘苹果。陶陶有个厘米高的板凳,当她不能直接用手摘到苹果的时候,就会踩到板凳上再试试。现在已知个苹果到地面的高度,以及陶陶把手伸直的时候能够达到的......
  • Linux下内存buff/cache占用过多问题解决
    在Linux下经常会遇到buff/cache内存占用过多问题,如果buff/cache占用过大的,free空闲内存就很少,影响使用;通常内存关系是:普通机器:total=used+free虚拟机器:total=used+free+buff/cache这个时候可以看到buff/cache占用的内存非常大,这个时候可以使用一下命令去清除一下cache内存echo1>......
  • 题解 P6880 [JOI 2020 Final] オリンピックバス
    洛谷。题意应该显然,注意最多只能翻转一条边,并且可以不翻转。分析首先观察数据范围\(2\leN\le200\),\(1\leM\le5\times10^4\),可以发现我们的\(N\)和\(M\)并不是同级的,因此,在众多的最短路算法中,我们应当选择不加堆优化的dijkstra算法,并且使用邻接矩阵,这是\(O(n^2)......