CF1294F Three Paths on a Tree
除去整棵树是一条链的情况,答案的构成应该是两条链拼在一起。考虑贪心,先找到直径,再枚举不在直径上的点,求出它们到直径的距离最大值与直径加和即可。最后特判一下一条链的情况。
CF1288E Messenger Simulator
首先最靠上的位置很显然是 \(1\) 或者 \(i\),移动过是 \(1\),否则是 \(i\)。
考虑如何求最靠下的位置。
一个很巧妙的做法是在数组前面添加 \(m\) 个点,初始为空,称为虚点,每一次操作将当前点从它原本的位置移动到前面的虚点中。用线段树或者树状数组维护每个点是否为空,统计答案时查询当前点前面非空点的个数即可。注意到最大值只会出现在每次移动前和所有操作结束后。
CF1288D Minimax Problem
最小值最大化问题显然可以二分答案,对于每次二分出来的 \(mid\),将矩阵中的数大于等于 \(mid\) 的置成 \(1\),小于 \(mid\) 的置成 \(0\),这样每一行就变为了一个二进制数(当然这样做是基于 \(m\le 8\))。所以 check 当前 \(mid\) 是否合法的方式为是否可以找到两个二进制数按位或起来全是 \(1\)。开一个桶,查找当前二进制数补集的超集是否出现过即可。
CF1280C Jeremy Bearimy
感性理解一下,对于距离和的最小值,肯定是让每个点与尽量近的点匹配,使得每条边被经历尽量少次,最大值则相反。
那么考虑贪心,先说最小值,对于一条边 \((u,v)\),如果 \(sz_{v}\) 为偶数,那么这个子树内的所有节点就可以两两匹配而不经过这条边。相反,如果是奇数,则一定会经过,对于会被经过的边,统计答案时加上它的边权即可。
在考虑最大值,还是对于一条边 \((u,v)\),它两侧点的数量分别为 \(sz_{v}\) 和 \(n-sz_{v}\),因为我们希望它被经过尽量多次,所以一定是让两侧的点互相匹配,那么最多被经过的次数为 \(min(sz_{v},n-sz_{v})\),最后乘上权值加和。
CF1268B Domino for Young
对网格黑白染色,一个骨牌一定覆盖在一个黑格和一个白格上,最多能放的骨牌数量就是黑格数量和白格数量取 min。
CF1266D Decreasing Debts
对于一个点如果既有出边又有入边,那么就将该点的这两条边权同时减去它们的最小值,这样就可以将所有点分为两大类,只有出边或者只有入边。可以理解为,一个人如果借给别人 \(a\) 元钱,欠人 \(b\) 元钱,那么对于这个人整体上来说只是欠或借别人 \(|a-b|\) 元钱。因为我们不在意边的个数,只要求边权和最小,所以两类边任意匹配即可。
CF1257E The Contest
首先将 \(n\) 个元素从小到大排序,\(dp_{i,0/1/2}\)表示考虑到第 \(i\) 个元素,它分别在第一、二、三个集合的最小操作次数。
转移方程显然:(\(a_{i}\) 表示 \(i\) 元素初始所在集合)
CF1256F Equalizing Two Strings
题目中并不在意操作的次数,所以不妨将 \(L\) 固定为 \(2\),即交换相邻字符。
首先如果每个字母的出现次数不同,那么输出 \(NO\)。
先考虑没有相同字母出现的情况,这样将第一个数组的字母顺序映射到第二个数组,形成一个排列。问题转化成将一个排列通过交换相邻数字变成升序排列,显然交换次数为偶数时合法,否则不合法。经典用逆序对求解,逆序对个数即为交换次数。
再考虑存在相同字母的情况,可以通过将逆序对数量 \(+1\) 或 \(-1\) 使得逆序对个数为偶数。
CF1256E Yet Another Division Into Teams
首先排序,同组的人一定是排序后连续的一段。容易想到这是一个 dp,dp状态显然:\(dp_{i}\) 表示将前 \(i\) 个人分组的最小极差和。
一个显然的结论是每组的人数区间为 \([3,5]\),所以 dp 转移时只会从 \([i-5,i-3]\) 转移过来,最后记录一下转移位置来划分方案即可。