首页 > 其他分享 >【做题笔记】dp,但是国庆限定版

【做题笔记】dp,但是国庆限定版

时间:2023-10-04 16:11:24浏览次数:28  
标签:笔记 节点 消掉 限定版 区间 col dp 方格

Day 1

方块消除

传送门

看到这个数据范围就可以猜测正解是 \(O(n^4)\) 的 dp,与这个差不多相符合的可以想到区间 dp。然后大胆猜测一下就是区间 dp,令 \(dp[i][j]\) 表示消除掉 \([i,j]\) 后的最大价值,这个显然可以从长度更短的区间转移过来。所以此题我们可以从区间 dp 的方向思考。

为什么不能用二维状态当普通区间 dp 做? 假如按照普通区间 dp 做,可以造出任意一组需要三个合并消除之后的数据卡掉。这是因为这种 dp 具有后效性,我们不一定要全部消除 \([i,j]\) 这一段的方格,可以取一些保留下来,等到两边的区间都被消掉之后再将它与其他颜色相同的方格连续起来消掉。

所以就有一种很难想到的状态设计,令 \(dp[i][j][k]\) 表示消除 \([i,j]\) 这一段块的区间,但是 \(j\) 是和后面的 \(k\) 个颜色相同的方格(注意不是块)连起来一起消掉的。

为什么不能一个块一个块做? 因为有可能最优解需要将一个块中的任意多个方格取出来先消掉,之后再消这个块中的其他块。

\(col[i]\) 表示块 \(i\) 的颜色,\(v[i]\) 表示块 \(i\) 的大小。设 \(sum[i]\) 表示在 \(i\) 后面有多少个与它颜色相同的方格。边界就是 \(dp[i][i][k]=(v[j]+k)^2(\;(k\le sum[i])\)。

在初始化的时候,为什么不加上由于要让后面 \(k\) 个块落到 \(j\) 旁边而消掉的区间的价值? 所以我们补充一下状态的设计,这个状态仅考虑 \(k\) 个颜色相同的方格已经和 \(j\) 相连了它们的贡献 + \([i,j-1]\) 这一段的贡献,也就是不考虑让 \(k\) 个方格连续过来的贡献。

对于 \(dp[i][j][k]\) 它有两种可能的转移:

  1. 单纯消掉 \([j,k]\)。
  2. 找到 \([i,j]\) 中一个与 \(j\) 颜色相同的块 \(l\),将它与 \(j\) 和 \(k\) 一起消掉。

对于转移 \(1\),我们可以枚举 \(k\;(k\le sum[j])\),\(dp[i][j][k]=dp[i][j-1][0]+(v[j]+k)^2\)

为什么 \(j-1\) 就不能接后面的东西了? 如果 \(j-1\) 接的方格 \(x\) 在最后一个 \(k\) 的前面,那么要么 \(col[x]=col[k]=col[j]\) 导致 \(x\) 被保留下来了,但这显然不可能,因为 \(col[x]=col[j-1],col[x]=col[j]\) 但 \(col[j-1]\ne col[j]\)。所以 \(x\) 不会被保留下来,它早就会被消掉。如果 \(j-1\) 接的方格 \(x\) 在最后一个 \(k\) 的后面,考虑将 \([j,k]\) 消掉之后再消 \([j-1,x]\),那么这实际上是一个更大区间的转移 \(2\),我们这时候并不需要讨论。

对于转移 \(2\),我们可以先枚举与 \(j\) 颜色相同的 \(k\),再枚举后面要接的方格数 \(l\),那么 \(dp[i][j][l]=max(dp[i][k][v_{[j]}+l]+dp[k+1][j-1][0])\)。也就是先将 \([k+1][j-1]\) 这一段区间消掉,让 \(k\) 和 \(j\) 连到一起,再将 \([i,k]\) 这一段且 \(k\) 是和后面 \(v[j]+l\) 个方格连在一起消掉的。

为什么 \(k,j\) 又可以当成一整块做了? 注意状态是指消掉 \([i,j]\) 这一段块的整个区间的最大价值,那么无论是 \(k\) 还是 \(j\) 最后肯定都会被消掉。

最后的答案就是 \(dp[1][n][0]\)。

这道题是一种具有后效性的区间 dp,类似的题还有 它的双倍经验: 方块消除 Blocks 祖玛

Recovering BST

洛谷传送门

看到二叉搜索树,可以想到它有一个很好的性质:中序遍历单调不降。然后想到了 加分二叉树 这题,就可以考虑区间 dp 了(

考虑瞎套那道题,设 \(dp[i][j]\) 表示 \([i,j]\) 这一段是否能变成一颗树。但是此题与根节点还有关系,这样的状态并不能知道根节点是谁,所以设 \(dp[i][j][k]\) 表示 \([i,j]\) 这一段且以 \(k\) 为根节点是否能变成一棵树。

然后看一眼数据范围,\(700\times700\times700\),空间直接爆炸。考虑优化。

一个常规的三维优化方式是将第三维变成只有几种取值的维度(参考类型:关路灯)。考虑是否有这种可爱的性质能让第三维变成只有很少的取值。

幸运的是,我们确实有这种性质!当 \([l,r]\) 这段区间变成一棵树的时候,当它成为下一个区间的右子树的时候,它的根节点是 \(l-1\),当它成为下一个区间的左子树的时候,它的根节点是 \(r+1\)。这里只需要证明出两种情况中的任意一个,另外一个就能类似地推出来,所以这里只证明成为右子树的情况。

若 \([l,r]\) 这段为右子树,那么根据二叉搜索树的性质,它的根节点一定比这一段任意数小,也就是比 \(l\) 小,所以根节点取值范围是 \([1,l-1]\)。我们假设根节点是 \(l-x\;(1<x<l)\),那么 \((l-x,l)\) 这一段也必定要放在 \(l-x\) 的右子树中,但现在右子树的形状已经确定为 \([l,r]\) 了。所以假设不成立,\(x=1\)。

为什么不能把 \([l,r]\) 这段区间中间的某个值提出来当根节点? 这样的策略是可行的,但是我们发现在这种树上你要把 \(i/j\) 提出来也是可行的。我们只需要判断是否可行即可,而这种可行的话 \(i/j\) 为根节点也可行,所以没必要那么麻烦。

因此,我们设 \(dp[i][j][0/1]\) 表示 \([i,j]\) 这段区间且 \(i/j\) 为根节点是否能成为一颗树。状态转移的时候可以枚举断点 \(k\) 表示是从 \([i,k]\) 和 \([k+1,j]\) 这两棵树合并起来得到的。显然首先要满足 \(dp[i][k][0]=dp[k+1][j][1]=true\)。接着讨论是 \([i,k]\) 接到 \([k+1,j]\) 这颗树上还是 \([k+1,j]\) 接到 \([i,k]\) 这棵树上。根据二叉搜索树的大小关系,\(k+1\) 一定是最左边的左儿子,\(k\) 一定是最右边的右儿子,接过来的话一定是 \(i\) 变成 \(k+1\) 的左儿子或者 \(j\) 变成 \(k\) 的右儿子。判断一下这两种情况的 \(\gcd\) 是否为 \(1\) 即可。

为什么不能是 \(dp[i][k][1]\) 什么的转移过来?\(k\) 和 \(k+1\) 怎么你了? 这实际上跟之前那个问题是一样的,只要其中一种可行,那么最后也可行,你硬要判断一下也可以过,但实测会慢一点。

最后输出的时候直接判断 \(dp[1][n][0]=true\) 或者 \(dp[1][n][1]=true\) 就行了。

为什么其他题解都说最后答案要枚举一下根节点? 我不知道啊,但 实测 这样是可行的。并且理论上来说树的形态不会影响答案是否可行,那么最后也没必要枚举根节点了。也有可能是数据太弱吧/kk。

Dreamoon and Strings

洛谷传送门

这题难点大概是想到 dp 吧,毕竟看题面怎么都是一道字符串匹配题(。但发现用字符串算法好像没有什么很好的方法解决这道题(至少我不会),再加上可以想到 编辑距离 那题,想到这种删删减减字符串的题还可以用 dp 写,就大胆猜测一下是 dp。

设 \(dp[i][j]\) 表示 \(s\) 中的前 \(i\) 个删掉 \(j\) 个字符后包含的 \(p\) 的个数的最大值。首先无论如何都可以写出这样一个转移方程,\(dp[i][j]=max(dp[i-1][j],dp[i-1][j-1])\),意思就是当前这个字符要不要删。如果 \(s[i]=p[m]\)(\(m\) 为 \(p\) 的长度),那么就表示加上这一位后可能会贡献一个新的 \(p\)。但是要从哪一个状态转移过来呢?我们可以处理一下 \(f[i]\) 表示以 \(i\) 为结尾恰好产生一个子串的最大起点位置。这个可以 \(O(n^2)\) 预处理出来。那么这样就可以转移了,\(dp[i][j]=max(dp[f_{[i-1]}][j-(i-f_{[i]}+1-m)])\)。转移的过程中判断一下数组可能越位的情况就行,注意 \(i-f_{[i]}+1-m\ge0\)

答案输出显然是 \(dp[n][i](0\le i\le n)\)。

标签:笔记,节点,消掉,限定版,区间,col,dp,方格
From: https://www.cnblogs.com/Arcka/p/17742310.html

相关文章

  • 《敏捷软件需求》阅读笔记一
    以下是关于敏捷软件需求这本书籍的前八章的阅读心得体会,涵盖了每章的主要观点和个人体会:第一章:敏捷方法概述    第一章介绍了敏捷方法的起源和核心原则,其中最关键的原则是个体与交互、工作的软件、客户合作和响应变化。我学到了敏捷方法的灵活性和迭代开发是应对不断变化......
  • 高维前缀和 (SOSDP)
    介绍一维前缀和:$s[i]=s[i-1]+a[i]$二维前缀和:$s[i][j]=s[i][j-1]+s[i-1][j]-s[i-1][j-1]$当然也可以这么写:for(inti=1;i<=n;i++)for(intj=1;j<=n;j++)a[i][j]+=a[i-1][j];for(inti=1;i<=n;i++)for......
  • HTML学习笔记——简单介绍
    什么是HTMLHTML:HyperTextMarkupLanguageHTML是一种用来告知浏览器如何组织页面的标记语言。其由一系列的元素组成,这些元素用来包围或者标记不同部分的内容,让它以某种方式呈现或者工作。简单拆分一个HTML元素观察下面一个HTML元素<p>HelloWorld!</p><p>HelloWo......
  • Java 学习笔记一
    dos环境下(Windows即cmd)的Java命令先用javac文件名.java;命令,编译java文件,生成一个后缀为class、名与类名相同的文件。再用java类名命令,执行文件。注释当类名前的修饰符为public时,类名必须和源文件名一致。并且以上操作不能执行带package的java文件。和C......
  • Qemu源码分析(11)—Apple的学习笔记
    一,前言昨天了解了qemu中虚拟开发板的内存创建,接着再了解下中断创建和使用。二,分析昨天看了flash初始化,后面的我理解应该一样,接着发现sram初始化后,本来以为和flash是一样的,结果多了如下一句,通过注释也很好理解就是把1个bit展开为了1个byte,这样1M的sram变成了32M空间。//Bitbandthe......
  • 10.4 国庆 环形dp与基环树笔记
    1.知识点环形dp环形dp的概念•环形dp与基环树在许多环形结构的问题中,我们可以在环中从某个位置把环断开,把这个环变成线性的,然后进行\(dp\)等操作。•把能通过上述操作解决的环形问题称作"可拆解的环形问题"。环形dp的两种策略•第一次在任意位置把环断开成链,按照......
  • 【文化课学习笔记】【化学】选必一:化学反应速率
    【化学】选必一:化学反应速率化学反应速率的相关概念及计算概念及数学表达式概念:化学反应速率是定量描述化学反应进行快慢的物理量。通常用单位时间内反应物浓度的减小或生成物浓度的增加来表示。数学表达式:\(v=\dfrac{\Deltac}{\Deltat}\)。由于速率一定是正值,所以浓度变化......
  • 笔记——树状数组
    蓝月の笔记——树状数组篇在可恶的OI里,我们尝尝会遇到一些区间问题,例如区间修改单点查询,单点修改区间查询,区间修改单点查询,单点修改单点查询。其中,单点修改区间查询,就是树状数组最经典的用法啦!Luogu-P3374给定一个长度为\(n\)的序列\(a_1,a_2,\cdots,a_n\)和两种操作:......
  • 【刷题笔记】67. Add Binary
    题目Giventwobinarystrings,returntheirsum(alsoabinarystring).Theinputstringsareboth non-empty andcontainsonlycharacters 1 or 0.Example1:Input:a="11",b="1"Output:"100"Example2:Input:a="10......
  • DP 总结
    最小包含串模型描述给定两个长度分别为\(n,m\)字符串\(s,t\),求出长度最小的串,使两个串都是这个串的子序列。基本解法设\(f_{i,j}\)表示第一个字符串前\(i\)个和第二个字符串前\(j\)个字符的最短包含串长度。边界:\(f_{i,0}=f_{0,i}=i\)。转移:\[f_{i,j}=\begin{ca......