在这片梦想之地,不堪回首的过去像泡沫一样散|

PassName

园龄:3年1个月粉丝:32关注:16

杭州集训 Day 3

课前

早饭 htdlz 帮忙买的,一碗粥和三个不知名的糕点,粥并不好喝,但是糕点好吃。

早上到了机房把这儿的小破电脑换成了自己的笔记本,屏幕大一点舒服一些。hs_black 走了,今天换 syksykccc 来讲,syk 开朗幽默的多,上课和机房这群很有话题。而且他甚至把他讲的每个题对应的代码打了,然后课后发了。

课前他自我介绍说:“我是高一拿的 Ag,后来觉的 OI 比 whk 难然后就 AFO 了,最后裸分考的北大。”

syk 还发表了一些逆天言论,如 “破链为环” 解决区间 dp 问题

笔记

P2051

f[i][j][k] 表示从左上角一直到坐标 (i,j) 并且用了 1~k 个象棋的方案数

n 的数据范围很小,可以 n3 暴力遍历

v[i][j] 标记棋子

但是转移并不好写,考虑找性质,发现对于每行每列炮的个数不会超过两个

所以将第二,三维优化

j 表示 有 j 个列是 1 个炮,k 表示有 k 个列放 2 个炮,剩下的放 0 个炮

转移的时候就考虑在当前行放 0/1/2 个炮,以及这些炮放在了之前有几个炮的列上

现在可以暴力转移,复杂度三次方级,可以通过

P1437

将原图形旋转变成左下角为直角的等腰直角三角形形式,那么想要拿走一个砖,就必须要拿走左边那个和左上角那个,考虑有依赖的背包 dp

显然的,可以将当前砖和左边那个和左上角那个绑定,他们的分值和为质量,个数为体积,然后背包

但是一定会有重复绑定导致计算错误,所以要考虑找特殊性质,发现第 i 行被打掉的一定是一个前缀,用 f(i,j,k) 表示当前考虑到第 i 行,这一行的轮廓线转折点在 j,已经打了 k 个砖头的最大收益。

f(i,j,k)=maxlj1{f(i1,k,kj)+Si(j)}

复杂度 O(n4)

P6189

显然可以平方级别的背包 dp,但是显然过不了。但是对于背包 dp 它也有两种不同的状态设计,

f(i,j) 表示把 i 拆成 j 的数的方案。g(i,j) 表示把 i 拆成 j 个数的方案。这个直接递推转移是非常好实现的。

之后根号分治,对于小于等于 n 的数据计算 f,剩下的计算 g(这里数据指的是 dp 第二维)

复杂度 O(nn)

之后考虑如何使用 f,g 更新计算答案

s=0n(f(s,M)×c=0Mg(ns,c))

M 指的是根号分界

P7962

将答案式子展开化简后为 ni=1nai2(i=1nai)2

对于一次操作,原来相邻两个数的差为 aiai1 变为了 ai+1ai。即一次操作是在交换差分数组的相邻两项,
可以任意交换差分数组得到一个新的差分排列。为了使所有数字趋于平均值,差分数组应当是单谷序列,微扰法可以证明。将差分数组 b 从小到大排序,然后依次考虑每一项,要么插在当前最左边,要么插在当前最右边。

a0=0,设 f(i,s) 表示考虑了前 i 个数,当前 ai=s
的情况下,最小的 ai2 是多少。

  • f(i,s+j=1ibj)=f(i1,s)+(j=1ibj)2,放在右边

  • f(i,bii+s)=f(i1,s)+ibi2+2bis ,放在右边

直接 dp 复杂度为 O(n2a)

注意到差分数组中非 0 项至多 O(a) 个,而对于 bi=0 毕竟排在最前面,无论放左放右都是一样的,所以直接铺开就行了,于是时间复杂度就能做到 O(na2)

P6764

计算出 Pi=0/1 表示能否从 i 开始进行一次粉刷,之后的就是很平凡的贪心区间覆盖问题。

假设现在 |Fc|1,那么每个墙能指派的承包商是固定的。用 f(i) 表示从第 i 段墙开始最远能刷到哪里。

f(i,j) 表示从第 i 段墙开始,让承包商 j 来粉刷,最远能刷到哪里。可以 O(nm) 逆序递推。初始化 0xcf,对于 jFci(i=N1(j+1)modmFci+1 的情况,f(i,j)=i。剩下的 jFci 的情况 f(i+1,(j+1)modm)

然后还有一些优化的 trick 卡一下就过了

P5289

f(x,y) 这样的状态去做背包,表示考虑到当前学校的时候,红阵营有 x 人,A 派系有 y 个人的方案数。复杂度是 O(nM2)

假如 k=0 发现可以先计算阵营的分配方案数,再计算派系的方案数,然后把两个乘起来即可。这两个都是可以一维背包实现的,复杂度 O(nM+cM)

对没有限制的学校用分别 dp 的方式,对于有限制的学校,因为不超过 k 个,所以用二维 dp 的方式再合并一下答案,总复杂度 O((n+c)M+k2sM)

P4302

f(l,r) 表示 S[l···r] 的答案。

  • 第一条:f(l,r)(rl+1)

  • 第三条:f(l,r)f(l,k)+f(k+1,r)

  • 第二条:枚举循环节长度 k
    f(l,r)f(l,l+k1)+2+digits((rl+1)/k)

枚举 krl+1 的因子的去检查,调和级数可得复杂度 O(n3logn)

P6879

时间值域太大了,不好设计进状态,但是答案很小,考虑交换定义域和值域设计 dp 状态。

f(l,r,blr,k) 表示当前考虑了 [l,r] 这一段的所有打卡点,
blr 表示终止时站在 l 还是 r,真正成功打卡了 k 个点时,最小花费的时间。用每一个已经求出的 f(l,r,blr,k) 的状态去更新 f(l1,r,,)f(l,r+1,,)k 是否要增加可以根据两个 b 的值很方便地计算。

那么初始时把所有的状态都赋值为无穷,如果一个状态的最小时间不是无穷就说明有意义,用它去刷表。最后要查看有意义的状态的 k 的最大值。

复杂度 O(n3)

P1864

不能修改数据值,所以这棵树的中序遍历固定。另一点是,由于可以修改为任意实数,实数是可以无限接近但是不相等的,所以完全可以理解为,允许权重相同,并且权重相同的点可以以任何你想要的顺序排序。即允许假定权重是整数来考虑这个问题。用 f(l,r,k) 表示把 [l,r] 建树并且保证子树内所有点的权重都 k 的时候,最小化的答案。f(l,r,k) 通过枚举根节点 t,分别考虑不需要 /需要修改,利用下两式来更新

f(l,t1,wt)+f(t+1,r,wt)+i=1rfreqi(wtk)

f(l,t1,k)+f(t+1,r,k)+K+i=1rfreqi

其中 freqi 表示深度 +1 之后代价的增量。总复杂度为 O(n4)

P7605

f(l,r) 为答案

转移 f(l,r) 考虑第一步选择了左边还是右边,不妨设左边。

如果最终都没消去,那么就是 f(l+1,r)+(1,1)

如果最终利用 ck 消去了,考虑一下 ck 是从左端取出的还是
从右端取出的。

不妨设是右端取出的,那么显然 [k+1,r] 要先被删除,考虑
枚举 j 表示 [l+1,j] 辅助了这一段的删除,那么转化后的子
区间就是 [j+1,k1]

max{f(j+1,k1),2,1+g(l+1,j,k+1,r)} 来表示这个转移

其中 g(l1,r1,l2,r2) 表示完全消除 [l1,r1][l2,r2] 所需要的栈的大小。当然也有可能为无穷,此时对应的状态不能用来转移

关于 g 的转移,考虑是先取出 l1 还是 r2

比如是 l1,考虑它和哪个位置配对,比如是和 ci,其中 i[l2,r2]。再枚举左侧辅助消除 [i+1,r2] 的区间是 [l1+1,j],那么转移就可以表示为 max{g(l1+1,j,i+1,r2)+1,g(j+1,r1,l2,i1)}

理论复杂度 O(n6) ,实际上可以快速判断一些 g 的值为无穷,比如区间长度和是否为偶数,区间内的数是否两两配对(可以哈希之后求异或
和)。这样常数很小。可以用记忆化搜索实现。

P7077

如果没有第 2 类,考虑计算每个第 1 类函数的实际被调用次数。

2 类函数可以看作,对原始数据的乘法 + 将之前的第 1 类函数调用 Vi 次。

建立一个 DAG,每个第 3 类函数(可以把 f1,···,fQ 也建模成一个第 3 类函数)向它所调用的所有函数依次连边。

首先考虑计算原始数据的贡献,这个只需要一次 dp 求出每个函数调用造成的全局乘积大小,然后就可以方便的计算总倍率。

逆序第 3 类函数序列。动态维护一个乘积 prod 表示当前子函数需要执行多少次。每遇到一个子函数,就在它对应的节点上打 +prod 标记,然后再更新 prod。这样便可以拓扑排序后利用 dp 求出每个函数需要调用的次数,累加贡献。

复杂度 O(n+Ci)

P4577

每个节点开一个 multiset fu,从大到小的第 x 个数,表示当答案为 x 时的最大转移权值。

首先不考虑 u 的话,fu=fv

考虑 u,那么把 wu 插入 fu,然后除非 wufu 中最小的,否则把 wu 的前一个 iterator 删除。合并 f 时可以使用启发式合并,复杂度 O(nlog2n),如果使用权值线段树维护可以做到单 log

P5024

f(u,0/1) 表示 u 的子树,u 不选 / 选,从“转移模式”来
看,除了 a,b,其他的点依然在做相同的操作。

首先一次 dp 求出前文提到的 f(u,0/1) 数组,现在考虑把 f 倍增化。用 g(u,k,0/1,0/1) 表示对于 u,它选不选,它的 2k 级父亲 fa 选不选,则 tree(fa)tree(u) 的最优代价。初始化为

g(u,0,0,0)=inf

g(u,0,1,0)=f(fa,0)f(u,1)

g(u,0,0/1,1)=f(fa,1)min(f(u,0),f(u,1))

倍增转移时枚举 2k1 级父亲的状态

现在分两种情况讨论询问。如果 a,b 是祖先-后代关系,那么,先用 bf 去初始化状态 res0,res1,分别表示当前的根节点是不选/选的最小代价。然后用 g 去倍增到 a,再把 resx 赋值为 0,最后一路倍增到根节点即可。如果不是的话,同理,分别从 a,b 用上面的操作倍增到 LCA 下方的节点,然后在 LCA 处暴力合并答案,再倍增到根节点即可。复杂度只有一个 log

课后

绝区零常驻池第一个常五是狼哥,第二个十连出了苍角,抽那个小不点不知道是什么的东西上来十连出了一个金,后来换成鲨什么蓝色的那只十连又出了。

暗示我抽鲨鱼妹

但是我 50 抽了还没出,运气太差

傻鸟米哈游不如洛谷好玩

本文作者:PassName

本文链接:https://www.cnblogs.com/spaceswalker/p/18494373

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   PassName  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起