sb课件的题解(复习)
不理解,为什么一个新的课件我就2题没做过,没救了
CF1310C
这题,我们发现它不同的子段共有\(n*(n-1)/2\)个,将其按字典序排序
我们需要便捷的比较,考虑维护\(lcp[i][j]\)表示第i个子段和第j个子段的最长公共前缀
每个方案都会被一个字典序最小的串代表,我们考虑二分S,每次求出最小串字典序>=S的串有多少个
考虑如何实现\(check\)函数
我们考虑dp,首先有个想法
\(f[i][j]\)表示S的\([1,i]\),分成j段的,且每段的字典序>=S的方案数
我们发现这样不方便转移,因为我们比较字典序的时候是从头开始的
如果我们用后缀匹配S的话,可以从头开始匹配
将状态改变,将\([1,i]\)改成\([i,n]\),考虑转移
对于i,如果\([i,j]\)满足字典序比S大的话,那么\([i,j+1],[i,j+2],...\)字典序都比S大,这就是个后缀和
我们需要便捷的找到\(j\),发现lcp同样可以求
然后\(Dp\)就可以\(O(n^2)\)求了,这题就做完了
CF1051E
我们设\(dp[i]\)表示前i个字母,分成若干段的方案数
我们现将前导零的情况特判掉
然后对于一段字母\([i,j]\),如果它们的长度x满足l<x<r,那一定是合法的
然后我们只需要特判长度=l,和长度=r的情况
比较直接二分+哈希即可
CF477D
我们维护两个dp方程
\(f[i][j]\)表示到了第i个点,\([j,i]\)分成一段的方案数
\(g[i][j]\)表示到了第i个点,\([j,i]\)分成一段的最少分段数
对\(f[i][j]\)维护前缀和,\(g[i][j]\)维护后缀min,方便转移
第一问很简单,\(f[n][n]\)
对于第二问,答案就是k+v,v就是最后一段的值,k就是分段数
我们发现2^17>5000,k 最多就是5000
所以最后一段分在n-16之前一定不优,因为v增加的超过了k的最大值
不过实现是直接用log+long double比较
CF1701E
好妙的DP题
我们考虑它的匹配过程
一定是现在后面删除一些数,然后运用\(home\)操作移到最前面,然后删除一些数
我们将其归纳为前缀、中缀、后缀,其中中缀是不被删除的、完整的、和t匹配的一段
我们设\(dp[i][j]\)匹配到S的第i个字母,T的第j个字母,删除字母的最小数量
当为前缀时:
\(dp[0][0]=1\)
\(dp[i][j]=dp[i-1][j]+2\)
\(dp[i][j]=dp[i-1][j-1]+1(s[i]=t[j])\)
当为中缀时:
\(dp[0][0]=0\)
\(dp[i][j]=dp[i-1][j-1](s[i]=t[j])\)
当为后缀时:
\(dp[i][j]=dp[i-1][j]+1\)
\(dp[i][j]=dp[i-1][j-1]+1(s[i]=t[j])\)
然后依次转移即可
CF696D
首先建立一棵AC自动机,然后在上面dp
\(f[i][j]\)表示到了第i个字母,处于AC自动机上的第j个点
然后直接矩阵优化即可
CF585F
好sb的题,好sb的题面
我的题面:
题目要我们求长度为d的串t,满足\(a<=t<=b\)
且它有长度至少为\(\frac d 2\)的子串满足同时也是s的子串
我们考虑差分,用\(<=b\)的满足条件的串 - \(<a\)的满足条件的串
满足条件的t肯定有长度为\(d/2\)的子串是s的子串
我们对s所有的长度为d/2的子串建立一颗AC自动机
然后\(dp[i][j][k]\)表示到了第i个点,当前在AC自动机的j号节点,是否还顶着上届
转移,我们考虑我为人人
如果\(dp[i][j][k]\)中的j满足是一个s子串的结尾,我们就不用它去转移了,防止算重(最后乘上方案数即可)
否则,直接枚举下一个字母即可
CF150D
我们将代价为-1的点代价改成-oo,那就一定不会选
我们设\(f[l][r]\)表示l~r区间操作能得到的最多积分
\(h[l][r]\)表示l~r区间全部删完能得到的最多积分
那么我们发现\(f[l][r]=max(max(h[l][r],0),max_{j=l}^{r-1} f[l][j]+f[j+1][r])\)
\(h[l][r]\)直接dp不是很方便,我们考虑将它的最后一次删除延后
设\(g[l][r][x]\)表示l~r的区间,删的只剩下一个长度为x的回文串的最多积分(下取max)
\[g[l][r][x]=h[l][j]+g[j+1][r][x]\\ g[l][r][x]=h[j+1][l]+g[l][j][x]\\ g[l][r][x]=g[l+1][r-1][x-2](s[l]==s[r]) \]那么\(h[l][r]=max(g[l][r][x]+c[x])\)
然后这题就做完了
CF1422E
设f[i]表示将后面i个字母进行操作的答案
s[i]=s[i+1],f[i]=min(f[i+2],s[i]+s[i]+f[i+2])
s[i]!=s[i+1],f[i]=s[i]+f[i+1]
然后就好了
标签:子串,题解,字母,课件,max,sb,我们,dp,字典 From: https://www.cnblogs.com/CHK666/p/16710207.html