do_while_true

一言(ヒトコト)

AtCoder [2000, 3199] 水

abc292g | A

没一眼看出来还是拉了。

考虑区间 dp,\(f_{i,l,r}\) 表示 \([l,r]\)\((i-1)\) 位都相同,看后面 \([i,n]\) 位填数使得递增的方案数是多少。

这样已经可以做了,但是还不够,要追求一下最简单的写法。想想,发现每次 dp 是要分为多个儿子乘起来,内部还要搞个 dp。但可以改成每次两个儿子乘起来的方式,那就是 \(f_{i,l,r,k}\)\(k\) 表示第 \(i\) 位要填 \(\geq k\),其余含义仍不变。

这样子就枚举 \(k\) 填了哪个前缀,时间复杂度是 \(\mathcal{O}(n^4|\Sigma|)\),采用记忆化搜索的写法。

Code

arc157d | B

假如有 \(cnt\)Y,行分为了 \(A\) 段,列分为了 \(B\) 段,那么 \(2AB=cnt\)

然后考虑竖着的分界线一共能从哪儿切,必须要保证每一段里面有 \(2A\)Y,然后从左往右扫知道扫满了 \(2A\)Y 之后,扫到下一个 Y 之前,那么这个分界线划分在这其中任意一个位置都是可行的,并且分界线之间的划分不会相互影响。横着的也同理,那就每个分界线的划分方案数乘起来就行。

时间复杂度 \(\mathcal{O}(d(HW)(H+W))\)

arc157e | B

特判 \(n=1\),Y 形成独立集,然后考虑 Y 的填法会给 YX 和 XY 带来什么影响。

  • 填 1:YX += 2
  • 填无儿节点: XY += 1
  • 填双儿节点:XY += 1, YX += 2

1 直接分类讨论掉,选它或者不选它两种情况,现在考虑填根也一样会 XY += 1 的情况:

如果没有 Y 形成独立集的限制,那么直接贪心就行了。

那就考虑,枚举选了几个无儿节点,那在双儿节点中就最多选多少个,那就是最大独立集。所以树形背包 \(f_{x,i,0/1}\) 表示 \(x\) 子树内选了 \(i\) 个无儿节点,然后 \(x\) 这个点有没有被选进独立集里,存的值是独立集里最多多少个双儿节点。

时间复杂度 \(\mathcal{O}(n^2)\)

abc290f | A

公式太长了,挂这里了。

abc290g | B

一定是枚举一个深度,从这儿断一下,只留这么高位 \(i\) 的子树,然后再删掉这个子树的若干个子树得到 \(X\).假设现在一共要删 \(Y\) 个点,那么将 \(Y\) 进行 \(K\) 进制分解,各个数位和即为答案。

arc159d | B

几个月前囤的 idea 被出了(虽然也是从 CF1474F 改编的)愤怒!愤怒!/fn/fn

用那个贪心,每次来一个 \(x\) 的时候如果能在最后接上就直接接上,否则找到第一个 \(>x\) 的位置将其替换成 \(x\)

放在这里就是 LIS 里面每个位置放着是一个按 \(1\) 递增的一个东西。如果能直接接在最后面就接,不能的话找到第一个数能够替换的位置,然后如果是按 \(1\) 递增那么就会逐渐替换后面的,否则就逐渐替换前面的。一段一段整体一起替换。均摊下来替换次数是线性的。

abc296h | B

考虑一行一行往下 dp,一个状态需要记录每个格子是否是黑色,对于黑色还有记录其并查集。爆搜跑一下本质不同状态数不是很多,dp 就行了。

\(m=7\) 的时候状态数只有 324.

abc295h | D

先找充要条件!一个矩阵合法当且仅当对于每个 1,要不然上面全是 1,要不然左边全是 1,然后轮廓线 dp,状压里记录每一列是不是上面全是 1,还要多记一下左侧是不是全是 1.

posted @ 2023-05-31 12:13  do_while_true  阅读(28)  评论(0编辑  收藏  举报