首页 > 其他分享 >[NOIP2015 提高组] 子串

[NOIP2015 提高组] 子串

时间:2024-10-03 19:12:30浏览次数:8  
标签:子串 NOIP2015 匹配 提高 显然 串前 递推

算法

状态定义

最初显然可以想到
\(f[i][j][k]\) 表示 \(A\) 串前 \(i\) 个, \(B\) 串前 \(j\) 个, 分割了 \(k\) 个子串
但是这样无法递推 \(k\) 维

于是加上一位 \(f[i][j][k][0/1]\), 最后一维表示是否选择 \(A\) 子串当前这一位, 也就可以递推的计算

状态转移

  • 当前位置不使用
    \(f[i][j][k][0]=f[i-1][j][k][0]+f[i-1][j][k][1]\), 显然

  • 当前位置使用
    \(f[i][j][k][1]=f[i-1][j-1][k-1][0]+f[i-1][j-1][k][1]+f[i-1][j-1][k-1][1] \leftarrow (a[i]==b[j])\)

边界条件

  • 对于A子串前i位,匹配B串第1个字符,那么只可能使用1个字符串,这种情况如果第i位不进行匹配,那么方案数就是之前所有能与第1位匹配的字符,所以 \(f[i][1][1][0]=sum(a[1~i-1]==b[1])\)

  • 同上,但如果B串第一位和A串某一位匹配了话,那么 \(f[i][1][1][1]=1\) 是显然的

答案

即为 \(f[n][m][k][0/1]\)

空间复杂度优化

一眼滚动数组

  for (int i=1;i<=n;i++){
        swap(now,pre); //交换,只要i改变
        f[now][1][1][0]=s;//边界1
        if (a[i]==b[1]) f[now][1][1][1]=1,s++;//边界2,解决了s统计的问题
        for (int j=2;j<=m;j++){
            for (int k=1;k<=t;k++){
                if (a[i]==b[j]){
                    f[now][j][k][1]=((f[pre][j-1][k-1][1]+f[pre][j-1][k][1])%prime+f[pre][j-1][k-1][0])%prime;
                }//方程2
                f[now][j][k][0]=(f[pre][j][k][0]+f[pre][j][k][1])%prime;//方程1
            }
        }
     for(int j=1;j<=m;j++)
          for(int k=1;k<=t;k++)
            f[pre][j][k][1]=f[pre][j][k][0]=0;//清空
    }

总结

状态的设计可以从需要递推的项中找灵感
注意初始值一般为一行或一个点

标签:子串,NOIP2015,匹配,提高,显然,串前,递推
From: https://www.cnblogs.com/YzaCsp/p/18445865

相关文章

  • 2024初秋集训——提高组 #29
    C.卡片放置题目描述有一些卡片,写着两个数字\(A_i,B_i\)。你要将这些这些卡片排列,其对于你的分数为\(\max(A_i,B_i)\cdoti\),对于对手的分数为\(\min(A_i,B_i)\cdot(N-i+1)\)。求令你的分数减对方分数的最大的方案数。思路我们来拆式子,这里令\(A_i\geB_i\):\[\begin{arr......
  • 南沙C++信奥赛陈老师解一本通题 1820:【00NOIP提高组】进制转换
    ​ 【题目描述】我们可以用这样的方式来表示一个十进制数:将每个阿拉伯数字乘以一个以该数字所处位置的(值减1)为指数,以10为底数的幂之和的形式。例如,123可表示为1*10^2+2*10^1+3*10^0这样的形式。与之相似的,对二进制数来说,也可表示成每个二进制数码乘以一个以该数字所处位置......
  • 【训练记录】2024年莆田市高中信息学奥赛国庆集训CSP-S提高组(第二天场外)
    训练情况rk#4\(100+100+100+70=370\)赛后反思没什么很严重的失误,只是国庆早八起不来,打到后面时间不够做第四题了QAQ,下次一定早起TATA题开场怎么是CFDiv4原题,显然因为\(a,b,c,d\)互不相同,最后切出来的结果只有三块或四块,三块的情况是两线没有交叉,四块的情况......
  • P1020 [NOIP1999 提高组] 导弹拦截
    P1020[NOIP1999提高组]导弹拦截参考材料需要抽象一下,第一问就可以抽象为最长不上升子序列,第二问可以抽象为最长上升子序列长度。就如下图的情况:然后可以先\(n^2\)做法做,因为\(n\ge100000\)所以要滚动数组,求最长不上升子序列可以反向从n开始递推。我是n^2我不好......
  • CSP-S/NOIP提高组 真题题解总结
    DP:线性dpP1091[NOIP2004提高组]合唱队形比较简单的一道题。求出以\(i\)结尾的最长上升子序列和以\(i\)为头的最长下降子序列,相加\(-1\)即可。P1052[NOIP2005提高组]过河如果不考虑\(L\)的范围,那么就是一道简单的线性dp。但是\(L\)很大,石头数量很少,......
  • 2024初秋集训——提高组 #28
    B.车轮战题目描述你将进行\(N\)场决斗。一开始你的战斗力为\(s\),咒术强度为\(x\)。每次决斗之前你可以选择:令\(s\leftarrows+x\)。令\(x\leftarrowx+1\)。每次决斗,如果你的\(s\gef_i\),则你赢得决斗。求最多能赢多少场决斗。思路我们可以发现,你最多会进行\(80......
  • 【训练记录】2024年莆田市高中信息学奥赛国庆集训CSP-S提高组(第一天场外)
    训练情况rank#15\(100+0+40+0=140\)赛后反思T3忘记负数取模,丢了\(60\)分T1.跑步显然,找到第一个大于\(t\)的\(a,b,c\)倍数,所以我们直接\(t\diva,b,c\)向上取整,再乘回去,最后减去\(t\)即可,注意一下ceil好像会爆#include<bits/stdc++.h>#definei......
  • 【PostgreSQL】提高篇——如何创建和使用自定义函数和存储过程,包括 PL/pgSQL 语言的使
    数据库管理中,存储过程和自定义函数是非常重要的概念,尤其是在使用PostgreSQL这样的关系数据库管理系统时。它们允许开发者将复杂的业务逻辑封装在数据库中,从而提高应用程序的性能、可维护性和安全性。使用PL/pgSQL语言编写的存储过程和函数可以实现数据处理、事务控制和复......
  • 2024初秋集训——提高组 #21
    B.网格游走题目描述你在一个\(r\timesc\)的网格图的\((1,1)\)处。每个格子上都有一个箭头和计时器,一开始,箭头等概率地指向右/下方,计时器上等概率地显示\([0,p]\)中的一个实数。当计时器归零时,箭头指向的方向会翻转,即向右变成向下,向下变成向右,并且计时器会重置为\(p\)。......
  • 如何在Java中实现自适应数据增强技术提高模型泛化能力
    如何在Java中实现自适应数据增强技术提高模型泛化能力大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!今天我们来探讨如何在Java中实现自适应数据增强技术,以提高机器学习模型的泛化能力。数据增强是一种通过增加训练数据多样性来减少过拟合的方法,尤......