• cf 1337E


    题目:传送门

    题意:给出两个字符串S和T, 和一个空字符串A, 每次将s的第一个字符放在A的前面或后面 ;求 A串 在这样的过程中 ,其前缀等于T的方法数 (若S=T=“a” , 字符‘a’可以往空串前插也可以后插,故是两种方法)

      设 dp(i,l,r) 表示 S串中的前i个字符 形成的字符串与 T串中的 [ l , r ] 完全匹配的方法数 ,由于 i 个字符形成的字符串长度为 i ,所以一定有 r-l+1 == i 。因此,dp(i,l,r) 可以简化为 dp(l,r) ;

      前缀等于T的A串 , 可以表示为 A = T + 任意串  ,A串长度为n  、 T串长度为m; 上述的与T串匹配 可以看做: 前i个字符形成的字符串  与  满足题意的A串匹配

      1. 若 s[i] == t[l] , 则有 dp(l,r) = dp(l,r) + dp(l+1,r)  , 前插 s[i]   【 s[i] 与 t[l] 匹配 ;状态转移:前 i-1 个字符形成的字符串  (  i-1 == r-(l+1)+1  ) 与 t[ l+1 , r ] 的完全匹配  + 前插 s[i]  ==》 前 i=r-l+1 个字符形成的字符串与t[ l , r ] 的完全匹配   】

      2. 若   s[i] == t[r] , 则有 dp(l,r) = dp(l,r) + dp(l,r-1)   , 后插 s[i]   

      3. 若   l > m  ||  r > m  , 则有 dp(l,r) = dp(l,r) + dp(l,r-1) + dp(l+1,r)  【这里的 > m 指的是 与在A串中的“任意串”进行匹配, 既然是 “任意串” 那么前插后插都满足】

    AC代码:(dp的预处理见代码注释)

     1 #include<bits/stdc++.h>
     2 #pragma GCC optimize(2)
     3 using namespace std;
     4 typedef long long LL;
     5 typedef pair<int,int> pii;
     6 typedef pair<double,double> pdd;
     7 const int N=3e3+5;
     8 const LL inf=(1uLL<<63)-1;
     9 const LL mod=998244353;
    10 const double eps=1e-9;
    11 const long double pi=acos(-1.0L);
    12 #define ls (i<<1)
    13 #define rs (i<<1|1)
    14 #define fi first
    15 #define se second
    16 #define pb push_back
    17 #define mk make_pair
    18 #define mem(a,b) memset(a,b,sizeof(a))
    19 LL read()
    20 {
    21     LL x=0,t=1;
    22     char ch;
    23     while(!isdigit(ch=getchar())) if(ch=='-') t=-1;
    24     while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); }
    25     return x*t;
    26 }
    27 char s[N],t[N];
    28 LL dp[N][N];
    29 int main()
    30 {
    31     scanf("%s%s",s+1,t+1);
    32     int n=strlen(s+1),m=strlen(t+1);
    33     for(int i=1;i<=n+1;i++) dp[i][i-1]=1;//dp[i][i]=dp[i][i-1]+dp[i+1][i]=2  (i,i-1)可以视为空串
    34     for(int i=1;i<=n;i++)
    35     {
    36         for(int l=1,r=i;r<=n;l++,r++)
    37         {
    38             if(l>m||s[i]==t[l]) dp[l][r]+=dp[l+1][r],dp[l][r]%=mod;
    39             if(r>m||s[i]==t[r]) dp[l][r]+=dp[l][r-1],dp[l][r]%=mod;
    40         }
    41     }
    42     LL ans=0;
    43     for(int i=m;i<=n;i++) ans+=dp[1][i],ans%=mod;
    44     printf("%lld
    ",ans);
    45     return 0;
    46 }
    View Code

      

  • 相关阅读:
    二叉树(前序,中序,后序遍历)查找
    插入查找
    归并排序
    解密Spring AOP 之AspectJ与动态代理基础知识
    常用的sql
    python 集合方法
    python 字典
    python 列表方法
    python 序列类型
    fake_useragent
  • 原文地址:https://www.cnblogs.com/DeepJay/p/12790554.html
Copyright © 2020-2023  润新知