初三下——NOIP 模拟赛(6~10)
6
Conclusion
T1 花了 80min 有点慢了。
T2 的 dp 前置都没看出来,需要多练。
果然,之前欠下的债又在 T4 体现了……
T1
注意到一次碰撞后下一次一定不会碰到,一直这样直到出去。二分找位置即可然后算一下贡献。
T2
dp 部分
重排过后肯定是 0 + 01 + 1 的形式。于是根据这个 dp。
上面的 dp 冗余在其对于段数枚举了分界点。于是我们考虑就对于当前这个元素 \(i\) 进行单独考虑。记录是否有了过渡态/第 i 个,下一个期望填什么。
转移需要点脑子。
正解部分
考虑这个东西的实质。其实就是一堆连续 01。所以我们把它们弄成 \(len\) 数组。进行选择。
然后 01 的情况就是 2 个位置。
这个问题本质上是删数,删最小。而分析一下可以知道不能删除连续的 2 个。
这样就变成了反悔贪心板题。讨论边缘即可。
T4
线段树版本就是楼房重建的方式。
核心思想是:从后向前操作,使得当前的状态都是确定的。
每次我们单独把这个块完整操作,所以剩下的数一定是留给后面删的;
如果删不完,ned -;
否则,加上当前的答案;ned = 这个块之前还需要删多少个
前面会欠下来,相当于
7
Conc
T1 写对拍!
T2 真是一道好思维好构造。T3 转化过后变成了一个典。
T1
这种贪心题一定要去写对拍。
T2
Step1:3 个数的情况
对于 \(a < b < c\),我们想让 \(a\) 尽量的小以至于 0
!如果能构造出一种方案,使 \(b \%= a\),那么可以在 log 次操作将 \(a\) 变为 0(证明:辗转相除求 gcd
设 \(t = \lfloor b/a \rfloor\),即是让 \(b -= t * a\)。
一个操作是 让 \(a <<= 1\),考虑二进制
从小到大枚举 t 的二进制每一位
-
= 1 $(a,b) $
-
= 0 \((a,c)\)
这样不仅每操作一次都让 a <<= 1,而且在该对 b 减的时候都减了。
总的操作次数不会超过 log^2。
Step2:普通的数的操作
我们考虑从低到高位,并且通过减操作使得 1 变成 0。
T3
前置结论:
选择的 \((i, j)\) 需要是合法的嵌套串,并且中间的都要删除。
因为合法的串满足 \(l = r\) 且 任意 \(s_l >= s_r\),可以删
((())) 移除中间一定不优,显然;只有把整个删了才有可能
upd on 5.4:讨论 \(l+1\) 即可。
pyt 做法记录:
考虑 S = ((((((( + T1 + T2 + T3 + ... + )))))))))
那么最外面这一圈都选;剩下的 123 考虑组合,那么要前缀嵌套单减,单调栈即可
\(f_i\) 相等就暴力判字典序,这个复杂度类似于 cdq 计算
实现的时候传链表,因为字符串时间很大
normal:
从后往前变成无后效性 dp(字典序)
\(dp_i = \min(s_i + dp_{i+1}, dp_{nxt_i})\)
确实主席树可以做
倍增比较 hash 值即可
这里是后缀哈希,按照定义做即可。
8
Conclusion
状态调整很重要。我觉得 dp 需要多练了。
至少 T2 这种原神题我觉得是怎么都必须场切的,怒。
T1 要能挖掘一些状态的性质进行优化,出的好。
感觉 T3 也不难,不能场切还是太菜了。
T1
30 分的 dp 很显然。
优化
发现你每次改变状态的上限是 \(d\),一共 \(n\) 次。
性质:一定有符合条件的一组 \(a'\),使得 \(a'_i=a_j+kd\)。
于是对于每个 \(a_i\) 有 \(n\) 个状态,那么状态数就变成了 \(n^2\) 个。(一个非常到不满的上界)
然后需要优化转移,显然的单调队列。
T2
真的是气死啦!原题不会做!
管tmd什么定理,自己推:
根据 dag 性质,同一层之间肯定是独立的。于是就是确定最小层数,子集 DP 转移即可。
T3
找到一个最小表示法。
我们设 \(dp_{S,i,0/1}\) 当前状态,最后一点,是否翻转。预处理两个字符串相接的情况。(hash)
考虑这个最小表示法其实就是减去了重复部分,这个东西可以 dp 处理极值。
T4
两个 dp 的相互转化。后面补。