dp 练习题 2024.2

dp 专场 *2。

CF1608F MEX Counting#

题意:给出 n,m,b1...n,求出有多少个长度为 n 的序列 a 满足 i[1,n], 0ain|mex{a1,a2,...,ai}bi|m

1n2000, 1k50

很简单的 dp,个人认为难度下位紫或更低(?)

考虑枚举 i=1,2,...,n,依次填写 a1,a2,...,an,并维护当前的 mex 结果,不妨设为 j。当前填的数有三种:

  • <j,并不会产生什么影响

  • =j,此时当前的 mex 会变大,变大多少取决于 j 后面一段已填过的数的个数。

  • >j,这个数字可能对未来有影响,但我们目前未知

直接 dp,设 f[i,j,k] 表示填完前 i 个数,并且 mex 结果为 j,其中还有 k >j

考虑 ai 的影响,如果 mex{a1,a2,...,ai1} 还是 j,那么 ai<jai>j,转移:

  • 如果 >j 的数字种类数不变:f[i,j,k]f[i1,j,k]×(j+k)

  • 如果 >j 多了一个数字种类:f[i,j,k]f[i1,j,k1]×k

注意我们不计算这 k 种数的取值贡献,而是他们之间的相对大小顺序

接下来如果 mex{a1,a2,...,ai1}<j,不妨设为 x,那么中间 [x+1,j1] 这一段一定都在前 i1 个数出现过,我们不妨直接拿其中 >x 中的一些填入这 (j1)(x+1)+1=jx1 个数中。由于我们已经考虑了相对大小顺序,直接拿最小的那几个填入即可。

  • 转移: f[i,j,k]f[i1,x,k+(jx1)]

总转移式

f[i,j,k]=f[i1,j,k]×(j+k)+f[i1,j,k1]×k+xf[i1,x,k+jx1]

j 个数为 O(m),前缀和优化即可做到 O(n2m)

实现时注意细节问题。 记录


CF1450G#

题意:一个小写字母组成的字符串 s,其中字母 't', 'r', 'y', 'g', 'u', 'b' 不会出现,还给定了一个有理数 k=ab

每次可以选择 s 中的一种字母,将 s 中所有的这种字母变成另一种字母,但有个条件:设这个字母出现了 c 次,需要覆盖这 c 个位置的最小区间为 [l,r],那么需要满足 k(rl+1)c

对于所有 s 中出现的字母,求出是否可以通过若干次操作使得 s 中全是这种字母。

1n5000, 1ab105

因为有 6 种字母不会出现,所以一共只有 20 种,可以考虑状压。

我们把字母分类,一类是一开始就不合法的,另一类是一开始合法的。

一开始已经合法的两种字母显然不需要合并,因此我们一开始需要将一种合法的字母合并到一种不合法的,然后产生一个新的状态。

如果还不合法则继续合并,直到这个字母合法,此时这是一个字母集合(合并的集合),然后把他作为一个新的合法“字母”继续合并。

f[S] 表示是否可以把 S 中的字母合并起来,并且合并出去。

  • S 中的字母分成两个合法集合,显然这两个集合可以分别合并出去,不需要额外合并起来:f[ST]f[S]andf[T]

  • 合并到一个本来不合法的字母:f[S{x}]f[S]

时间 O(3n),需要优化。

注意到如果两个集合 S1,S2(S1S2=) 对应的覆盖区间有交,且 S1,S2 都是合法的,那么 S1S2 一定是合法的。

观察这能给我们什么思考,我们在第一种转移中枚举 T,如果 ST 对应的覆盖区间有交且 f[S]=f[T]=1,那么一定得到 f[ST]=1

进一步的,钦定 ST 都是由若干个合法的集合合并到一个不合法的字母形成的,设这两个字母为 x,y,设 S=S{x},其实我们可以先把 TS 合并,再转为 x。由于 S,S,T 都合法,如果去掉 xS,T 对应区间仍然有交,则 f[ST]=1;如果无交,通过第一种转移也可以使得 f[ST]=1

对于 S,T 由多个集合合并起来的,可知每个集合都合法。拆分每个集合,如果可以找到一条分界线来分划这些集合对应区间显然合法;如果找不到,依次合并起来就好。

因此,第一种转移时,我们枚举的 S,T 额外保证 S,T 对应区间无交,即可优化。设 k 为字母种类数,时间 O(k2k)记录


CF1621G Weighted Increasing Subsequences#

题意:给出 n,a1...n,对于每个上升子序列 ai1,ai2,...,aim,子序列中 aij 有贡献当且仅当存在 k 满足 k>imaij<ak,求所有上升子序列的贡献和,模 109+71n2×105, 1ai109

考虑把 a 转化为一个排列 p,相同的数则前面比后面大。不妨考虑 q=p1p 的上升子序列仍然对应 q 的上升子序列。对于一个上升子序列,设结尾位置为 x,那么子序列中的一个位置 y 有贡献的条件是一个位置 z 满足 z>yqz>qx

我们只需要用总方案数减去不合法的即可,不合法的条件是不存在 z 满足 z>yqz>qx,相当于 qxqy...n 的最大值。

我们对于每个位置 i 考虑其贡献,设 qi...n 的最大值位置为 w,我们要算的就是包含 i 且以 w 结尾的上升子序列个数,为 q1...ii 结尾的上升子序列个数 ×qi...wi 开头以 w 结尾的上升子序列个数。前半部分好做,注意 w 是由 i 更新的,不更新时直接维护,更新时只需要清空树状数组,时间 O(nlogn)记录


CF582D Number of Binominal Coefficients#

题意:给出质数 p 和整数 α,A,求有多少对 (n,k) 满足 0knApα|(nk),答案模 109+71p,α109, 0A101000

Kummer 定理:(a+ba) 中质数 p 的次数为 a+bp 进制下进位次数。

感性证明:考虑对初始为 0 的数连续做 n+1,在 p 进制下会进位 np+np2+... 次,这相当于 n!p 的次数。而 (a+ba)=(a+b)!a!b!,相当于连续 a+b+1 的贡献,然后去掉 ab 各自进位的贡献。

p 进制就可以直接数位 dp 了。

细节有点多,记录


CF1103D Professional layer#

题意:给出 n,k,a1...n,e1...n,一次性修改 x 个数(x 自己定),对于每个修改的数 ai,选择 ai 的一个约数 d 修改为 aid,使得最终 gcd(a1,a2,...,an)=1,求最小的 xiei1n106, 1k,ai1012, 1k1012

先求出 gcd,设为 gg 中质因子最多 10 个,设实际个数为 m

我们只关心 aig 中的质因子,求出每个质因子的次数。不难发现每个质因子次数都相同的两个数除了 ei 是等价的,考虑分为若干个等价类,求出每个等价类的前 m 小的 ei 分别是多少。

搜一下,等价类差不多一万多一些,比较少。

然后直接状压 dp,设 f[i,j,S] 表示前 i 个等价类处理的质因子集合为 S,修改了 j 个数,最小代价是多少,直接转移即可,时间 O(可过)记录

CF1784E Infinite Game#

题意:一个由 a 和 b 构成的字符串 s,长度为 n。两个人 Alice 和 Bob 在玩游戏,第 i 场中如果 s(i1)modn+1 为 a 则 Alice 赢,否则 Bob 赢。两人遵循三局两胜原则:每当一个人胜场满两场时,称那个人赢了一轮,然后清空胜场记录开始新的一轮。设 wi 为前 i 轮中 Alice 赢的轮数,当 i 时若 aii>12 则 Alice 是赢家,若 aii=12 则两人平局,若 aii<12 则 Bob 是赢家。现在 s 中挖了一些空,求所有可能的 s 中 Alice 赢、两人平局、Bob 赢的方案数分别是多少,模 9982443531n200

确定 s 后,设有 n 个点 0,1,2,...,n,每个点表示当前轮结束后的位置,每个点向下一轮结束的点连有向边,不难发现这些点形成基环树,所以游戏一直无限进行下去时,一定是一直在环上绕。

Alice 赢的条件是环上 Alice 赢的轮数比 Bob 多,Bob 赢的条件是 Bob 赢的轮数比 Alice 多,平局的条件是一样多。

每次经过 0 时可能不是完整一轮,有 4 种状态(每人可能得 0/1 分)。考虑每个状态扫过一个 s 后的得到的状态,这些状态形成基环树,找到这个环即可。

现在需要知道谁赢,可以考虑记下环上的状态的 Alice 赢的轮数 - Bob 赢的轮数总和,计入状态,但问题是我们根本不知道哪些状态在环上。可以一开始先暴力枚举是哪些状态,然后 dp,最后计算时判断一下。

时间复杂度 O(n2),常数为 24×44,可过。

记录


CF1842H Tenzing and Random Real Numbers#

题意:有 n 个变量 x1...n,在 [0,1] 中随机取值。有 m 条限制,每条形如 xi+xj1 或者 xi+xj1,求满足所有限制的概率。 1n20

考虑 xi+xj1 转化为 xi+xj20.5,这样相当于对一对变量的平均值限制为 0.50.5

考虑一开始有一条 0.5 的分隔线,我们按照与 0.5 差的绝对值从小到大加入变量,每次可以加在最上面或者最下面。

f[S] 表示加入的变量集合为 S 的合法概率。加入 xi 在上面时,不难发现 xiS 中每一个变量的平均值都 0.5,判断一下即可。

然后每个变量在上面和在下面概率为 12,这些变量与 0.5 的差的绝对值的每一种可能的大小顺序概率为 1n!,乘上就行,O(n2n)

记录


CF1874E Jellyfish and Hack#

题意:一个排列 P,定义 w(P): 我们把 P2...nP1 为根据分成 <P1>P2 且相对顺序不变的两个序列 L,R,然后 w(P)=|P|+w(L)+w(R)

求出多少种长度为 nw(P)lim 的排列 P,模 109+71n200, 1lim109

lim 过大没有用。容斥,改为求 w(P)<lim

一个显然的 DP:设 f[i,j] 表示有多少个长度 i 的排列,且其 w 值为 j

f[i,j]=k=1il=0jf[k1,l]f[ik,jl]

卷积,设 Fi(x)=jf[i,j]xj

那么

Fi(x)=k=1iFk1(x)Fik(x)

接下来很妙的一步,考虑带入 x,拉插插出多项式 Fn(x)

可知次数为 k=n(n+1)2,带入 k+1 个不同的 x,为 x=1,2,...,k+1

然后我们可以把卷积改成点乘,dp 是 O(n4) 的。

然后拉插插出多项式,有 k+1 个点值。对于第 i 个,分母是容易算的,分子是 j=1nxxjxxi,上面部分预处理,下面直接暴力除。

时间复杂度 O(n4)

记录


CF1804H Code Lock#

题意:有一串密码,长度为 n,由前 k 个小写字母组成。有一个密码盘,输入密码时,每秒可以

  • 输入一个小写字母

  • 将箭头往左移一格

  • 将箭头往右移一格

请设计这个密码盘(包括初始箭头指向),使得输入密码的秒数最小,求出这个数,以及有多少种设计方案。 1k16, 1n105

首先对于密码串,我们可以只保留 cnti,j 表示字母 i,j 出现相邻的次数。这样,密码盘的代价就是 ijdist(i,j)×cnti,j,其中 dist(i,j) 是两个字母之间的最小移动次数。

关键问题是他是一个环,两个字母之间有两种移动方式,我们难以判断是顺时针移动还是逆时针移动。

pi 表示字母 i 的位置,那么 i,j 之间的距离就是 min(|pipj|,pi+npj,pj+npi)

我们很容易想到需要把式子拆掉,然后两个字母分开贡献。但是仍然无法处理 min 和绝对值的问题。

先考虑 k 为偶数的情况。仔细思考,两种移动方式的距离的分割线是 k2,考虑折半的方法,我们可以在 k 中间砍一刀,然后左边和右边同时从前往后填字母。这样一来,不难发现,填写字母时,我们很容易知道他对于哪些段的贡献是怎样的。

如上图,S,T 是已经填写的字母集合,而 S,T 未填写。当我们给 S 最前面的位置(S 的后一个位置)填写一个字母 x 时,不难发现对于 ST 中字母,x 与他们的移动距离就是位置相减,其中 px 的贡献应是减去,系数为 y{ST}cntx,y。同理,对于 S,T 贡献应是加上。

为了知道 S,T 中分别是哪些字母,我们需要提前枚举左边和右边的字母集合。

转移考虑枚举 S,T 后分别填写字母 x,y,然后计算各自的贡献。

这样的转移是 O(k2) 的。由于 x,y 之间两条路径长度是一样的,考虑让 x 归为 S,让 y 归为 T 来计算。为了避免需要额外计算 x,y 之间的贡献,我们转移可以考虑拆开枚举:先枚举 y 来从前面转移过来,再枚举 x 把当前转移到后面,这样可以做到 O(k) 转移。

最后考虑 k 为奇数的情况。我们让左边部分后面多一个字母,容易处理,可以发现正确性也是对的。

时间卡一卡就能过了。

记录

出处:https://www.cnblogs.com/Sktn0089/p/18030431

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   Lgx_Q  阅读(35)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up light_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示