26 Sep
28
P6927
由于 \(a<b\) 和 \(a>b\) 对内存大小的影响不同(增加 / 减少),想到讨论 \(a\) 和 \(b\) 的大小关系。
同时采用邻项交换的想法,当 \(a<b\) 时,对于 \((a_1,b_1),(a_2,b_2)\),不妨钦定 \(a_1\le a_2\),然后分析可以得出 \(12\) 和 \(21\) 的代价;
\(a>b\) 时同理,但你发现 \(a_1\le a_2\) 时无法判断大小,此时要换成钦定 \(b_1\le b_2\).
排序后发现先做 \(a\le b\) 来增加内存是更优的,于是也不需要对如何拼接两部分讨论了。扫一遍求答案即可。
bonus: 还存在推式子做法,不过最后还是要分讨。
AT_dp_X
这种限制肯定要背包。但承重的限制不好确定转移顺序。
于是考虑用贪心来确定转移顺序。分析若 \(x\) 放在 \(y\) 上方能比 \(y\) 放在 \(x\) 上方承受更重的物品,此时 \(x\) 和 \(y\) 之间的关系,然后排序,靠前的物品放在上方更优。
然后按照这个顺序在底部加入物品转移,此时总重除自身外就是承重,可以方便地判断,直接 \(01\) 背包即可。
AT_agc023_F
题目中的顺序限制 dfs 序完全可以满足,于是开始考虑 dfs 做。可以对子节点邻项交换然后排序。但样例 \(3\) 告诉你下一个点可以在全局范围内任意跳,所以 dfs 做不了。
既然是全局问题,那直接把所有点加入堆全局排序。堆顶的元素都希望尽早走到,于是将其与 \(par\) 合并,这样 \(par\) 一被走到就可以直接走下来。用 Dsu 维护这个过程,并在合并时统计答案。
P7831
首先可以有一个直观的 dp。设 \(f_u\):从 \(u\) 开始无限游走的最小初始资产,然后对于边 \((u,v,r,p)\) 有 \(f_u\leftarrow \max(r,f_v-p)\). 但图上有环没法做。
观察性质:
- 若某点没有出边,则其一定没有答案(走不到环)。
- 若初始资产为全局最大的 \(r\),则一定可以不被限制。
于是先删掉所有出度为 \(0\) 的点,然后按 \(r\) 降序遍历每条没被删的边,然后可以令 \(f_u=r\),答案不会比这个更小,然后删掉这条边。
若出现出度为 \(0\) 的点,再用上面的式子转移,然后删掉这个点。重复做到没有点就得到答案。
P2751
使 \(n\) 个工件尽早完成 A 工序,必然选择所有完成时间中最早的前 \(n\) 个。于是把 \(m_1\) 个机器的完成时间加入堆,重复做 \(n\) 次即可。
同理可以求出 B 工序的前 \(n\) 个完成时间。然后显然首尾配对可以最小化最晚完成时间。
29
AT_arc098_D
正难则反,考虑把过程倒过来,记 \(C_u = A_u - B_u\),则进入点 \(u\) 至少要有 \(\max(0,C_u)\) 元,且第一次进入时获得 \(B_u\) 元。那么这个过程中钱数是单调不降的。
既然这样就希望能一次把邻域内的能走的点走完。考虑根据 \(C_u\) 建出 kruskal 重构树:按照 \(C_u\) 升序依次激活每个点 \(u\),若此时邻域内有其他已经激活的点,则将 \(u\) 向这个点所在连通块的根连边,并令 \(u\) 成为新的根,这样父权值总是大于子权值。
于是策略就是每到一个点就把其子树内所有点都走完。设 \(f_u\) 为从 \(u\) 子树内走到 \(u\) 的最小初始钱数,\(s_u\) 为 \(C\) 子树和。
那么有转移 \(f_u=\min\limits_{u\to v}\{\max(f_v,C_u-s_v)\}\)。最终答案为 \(f_{rt}+s_{rt}\).
P3523
显然首先可以二分。然后判定能否使用 \(m\) 个标记在 \(mid\) 步内覆盖所有关键点。
考虑自下而上递推,记录当前最远未被覆盖的关键点和最近的标记,维护完信息后分讨得出当前点是否必须标记。
UOJ839
首先把原序列看作一个操作。对每个操作维护 nxt 表示其开始覆盖的位置。
逐位贪心,每次取出 nxt 能覆盖到当前位且最大的数,将这一位的答案设定为它。
然后找出这一位是最大值的操作中最小的右端点 \(R\),将这一位上其他所有操作的 nxt 与 \(R+1\) 取 \(\max\).
因为这一位选最大后至少 \(i\sim R\) 全都会被确定,不再可能被其他覆盖。
P6005
首先忽略天数的影响。直接 dp 计算每天每个点可能获得的最大钱数。
即使这样也只有 \(O(nm)\). 直接枚举天数减去 \(C\times T^2\) 即可。
P8186
每头牛向其可能的交换对象连单向边,置换环上的牛都能换到礼物。
判环使用 Floyd 传递闭包,对于 \(x\to y\),当 \(f_{x,y}=1\land f_{y,x}=1\) 时有环且 \(x\) 可以换到 \(y\)。
30
NOICA R6T1
第一眼看出来这个数每次翻倍,爆搜层数 \(O(\log x)\),加上记忆化感觉很可做。但是即便如此每次枚举下次加的数仍然耗费了大量时间。
于是你发现这个东西从后往前做就可以后缀和解决,dp 就行了。
NOICA R6T2
首先注意 \(k\le 10\). 如果建分层图的话空间会炸,于是写了个 Dijkstra 的 dp。现在看起来这没有任何道理,不知道为什么过了 \(7\) 个点。
既然 \(k\le 10\) 应该直接一点:状压 dp 来考虑 \(k\) 个点走的顺序,类似 Hamilton 路径。点与点之间的距离直接 \(k\) 次单源最短路求得。
补题的时候因为忽略 \(k=0\) 的情况和 \(2^k\) 写成 \(2^n\) 调了半天,糖完了。
NOICA R6T3
对这种东西构造二位前缀和来达到它,发现是主副对角线上的一串 \(1\) / \(-1\). 那么这个东西直接做对角线差分就行了。
赛时想到了这里,但实际上要处理一对乱七八糟的边界问题,最后调不出来干脆换暴力。
实际上根本不用这么麻烦,边界难考虑就去掉边界:允许负数和超过范围的数存在,它们的范围至多是 \([-n,2n]\). 最后在 \(3n\times 3n\) 的网格上直接做就好了。
NOICA R6T4
图论建模题。考虑 \(A_i\) 和 \(B_i\) 连边,那么交换两者相当于对边定向,有出边的归属 \(A\),有入边的归属 \(B\).
那么 \(\operatorname{mex}(A)\) 就是最小的出度为 \(0\) 的点,\(\operatorname{mex}(B)\) 同理。若对于一个点有入边也有出边,则认为它能同时在两个集合。
然后 \(1\sim n\) 被划分为若干个连通块。若某个连通块有环,则叶子(即度数为 \(1\) 的点)需要被划分到 \(A\) 或者 \(B\)。这样把所有这样的点都固定分到 \(A\)。
若某个连通块无环,则不妨令其中最大点为汇点(分给 \(B\),其邻域内所有点指向它。显然不劣),其余叶子就为源点。
这样把尽量多的点扔进了 \(A\),可以使答案更优。因为每个点在 \(A\) 还是 \(B\) 造成的贡献是等同的,集中在 \(A\) 反而能凑出更多的连续段。
浙公网安备 33010602011771号