XYD1006CSPS

T1 密钥 [关键结论,模拟,枚举]

Description

给定两个长度为 \(n\)\(01\) 序列 \(a\)\(b\),每个位置都有一个权值 \(c\)
每次操作可以将 \(a\) 中一个位置取反,花费为操作后 1 的位置的权值之和,
求将 \(a\) 变成 \(b\) 最小花费。
\(n\le 5\times 10^3\)

Solution

下文将以类似 \(0/1\) 的形式表示 \(a\)\(0\)\(b\)\(1\)
手模样例加推理发现一个关键性质,对于 \(1/0\)\(0/1\) 这两种形式,肯定先把 \(1/0\) 按照权值从大到小变成 \(0/0\),再把 \(0/1\) 从小到大变成 \(1/1\),很好理解,证明简单,这里不再赘述。
但是有种特殊的形式 \(1/1\),可以在上面的操作中,先变为 \(0/1\),最后再变回 \(1/1\),以减小花费,但是我们并不能直接算出要变哪几个 \(1/1\),但是可以知道的是,这几个 \(1/1\) 一定是所有 \(1/1\) 中最大的几个。
于是考虑枚举前几个 \(1/1\) 需要和 \(1/0\) 合起来排序变为 \(0/1\)\(0/1\),再和 \(0/1\) 合起来排序变为 \(1/1\),即可。
排序可以用 set 维护,也可以用双指针,但不能每次都 sort()。

Summary

这题考察了观察和推理能力,以及一些码力,赛时需要多手模样例,多思考,推性质。

T2 科研基地 [树形背包DP]

Description

给定一棵带权树,求一个连通块,使得不在连通块内的点不超过 \(k\) 个,且连通块所有边权之和乘二最小。
\(n\le 10^4\)\(k\le 20\)

Solution

由于 \(k\) 很小,而且是个类似容量的东西,所以我们考虑 树形背包。
\(f(u,i,j)\) 表示在以 \(u\) 为根的子树中,考虑前 \(i\) 个儿子,有 \(j\) 个点不选的最小答案,转移如下,
\(f(u,i,j)=\max(f(u,i-1,j-t)+f(v,cntson_v,t)+w_{u,v}\times 2)\)
其中 \(i\) 这一维用滚动数组滚掉即可。

那么统计总答案只需要枚举每个点的 \(f\) 即可,这样为什么不会漏掉答案呢,为什么不需要 换根DP 呢,因为答案一定是个连通块,所以它一定在以某个点为根的子树,因此这样一定会枚举到最优答案。

Summary

普通的 树形背包 题,重点是最后统计答案时的一个小 trick。

上一篇:基于FPGA的多路视频缓存


下一篇:C++仿函数( 调用运算符重载)