[LGR-161-Div.3] 洛谷基础赛 4

A. Judg.

Problem

逐个判断即可。

B. Maps.

Problem

要让字典序最小,答案必然是一段前缀 \(0\) \(+\) 一段 \(01\) 交替的序列。

满状态是 \(1010\dots0101\),所以 \(2p+1> n\) 时无解。

后续直接从后往前模拟。

C. Colo.

Problem

好题

题意:给定个长度为 \(n\) 的序列 \(a,b\) 分别代表颜色和价值,你可以挑一些不同的颜色 \(a_i\) 进集合 \(S\) 中,获得 \(b_{a_i}\) 价值,但需要使所有 \(x\in S\)\(a\) 中按顺序取出后形成的序列单调不降。 求 \(|S|=k\) 时能获得的最大价值。

\(1\le n,k \le 500\)\(1\le a_i\le n\)\(1\le b_i\le10^9\)

把每种不同的颜色看成一个线段 \([\text{fir}_{a[i]},\text{end}_{a[i]}]\),其中 \(\text{fir}_{a[i]}\)\(\text{end}_{a[i]}\) 分别是颜色 \(a[i]\) 第一次出现的地方和最后一次出现的地方。不难发现如果当前保留了两种及以上的颜色,那么所有线段都应该是互相隔离的(即既不包含也不相交),这样才能确保最终序列的单调性。

现在相当于确定了一种 \(a[i]\),我们可以去区间 \([1,\text{fir}_{a[i]})\) 去寻找一个 \(\text{end}_{a[j]}\),这样 \(a[i]\) 就可以从 \(a[j]\) 那转移过来。

这样就转化为了一个类背包问题,用 dp 求解。

\(dp[\text{end}_{i}][len]\) 表示目前选择到了颜色 \(i\) ,已经选了 \(len\) 种颜色。

转移方程如下:

\[\normalsize{dp[\text{end}_i][len]=\max\limits_{j=\text{end}_{a[j]}\text{ },\text{ }j\in [1,\text{fir}_i)}(dp[j][len-1]+b[i])}\]

答案即为 \(\max\limits_{i\in [1,n]}dp[i][k]\)

有点抽象,看代码可能更直观。

这和一般的 dp 有点不一样,所以看起来很奇怪。

我们分析它的正确性是如何保证的:

  1. 外层从小到大枚举颜色 \(i\),保证不会从比它大的颜色转移过来,使序列单调不降。
  2. 用右端点 \(\text{end}_{i}\) 代表该种颜色,只保留有用的部分,符合最优子结构性质。

时间复杂度 \(O(n^2k)\)

D. Bina.

Problem

毒瘤

题意:给定正整数 \(n,m\),依照给定代码建一棵构建参数为 \(n\) 二叉树。你可以从二叉树底部开始往上砍节点(或不砍),一次砍一层,至少砍 \(m\) 个点。令美丽值 \(=\) 所有节点编号之和 \(\div\) 这棵树的深度(向下取整),求最大美丽值。

很难下手,但你可以把 \(n=1\sim 16\) 的图都手玩出来,找到一些性质。

这是 \(n=13\) 的图。

1

最明显的是这颗树除去最后一层必然是满二叉树,而且最后一层的叶子节点必然成对出现。

再进一步,\(n\leftarrow n+1\) 时就会多出两个节点,所以总节点数量 \(2n-1\) 是已知的,进而树的深度 \(d\) 也能推出。

其次一颗 \(d\) 层的满二叉树,其美丽值为 \(\frac{(1+2^{n}-1)(2^n-1)}{2}\times \frac{1}{d}=\frac{2^{n-1}(2^n-1)}{d}\),单调增。

意味着尽可能保留满二叉树层数是最优的。

\(m>0\) 时,最后一层必砍,在此基础上砍够 \(m\) 就马上停手,答案最优。

麻烦的是 \(m=0\),这意味着答案是从砍最后一层和一点不砍之间取较大者。

前者可以预处理,后者我们需要知晓最后一层的节点编号和。

找规律。

打印出 \(n=2^3\sim 2^4\) 时是哪些编号(设为 \(x\))的节点下挂了两个新节点。

\(n=\)\(8\)\(9\)\(10\)\(11\)\(12\)\(13\)\(14\)\(15\)
\(x=\)81210149131115

都减去 \(2^3\) 有:

\(n=\)\(0\)\(1\)\(2\)\(3\)\(4\)\(5\)\(6\)\(7\)
\(x=\)04261537

此时我们发现 \(x\) 是对应 \(n\) 的二进制翻转。

\(k=n-2^p-1\)\(rev(i)\)\(i\) 的二进制翻转。

又由于 \(x\) 下挂的两个节点编号为 \(2x\)\(2x+1\),最后一层的总编号和即为: \[\begin{align}&\text{ }\text{ }\text{ }\sum\limits_{i=0}^{k}(((2^p+rev(i))\times 2)+(2^p+rev(i))\times2 +1)\\&=(k+1)(2^{p+2}+1)+4\sum_{i=0}^k rev(i)\end{align}\] 由表推出 \(p=d-1\)。那么如何求 \(\sum\limits_{i=0}^k rev(i)\)

拆位考虑,考虑 \(0\sim k\) 中每个数的第 \(x\in[0,p)\) 位为 \(1\) 的个数 \(cnt\),对翻转后的贡献即 \(cnt\times 2^{p-x-1}\)

单组总时间复杂度 \(O(\log n)\)

利用二进制下第 \(x\) 位每隔 \(2^x\) 个就改变一次的特性,统计循环节,可以 \(O(1)\) 统计每一位的 \(cnt\)


[LGR-161-Div.3] 洛谷基础赛 4
https://kisuraop.github.io/posts/26a0ed02.html
作者
KisuraOP
发布于
2023年10月5日
许可协议