AT3741 String Problem 题解

题意

给定两个字符串 s s s t t t,可以对 s s s 字符串进行如下的两种操作:

  • 对字符串 s s s 的任意位置删去 A A A 字符。

  • 对字符串 s s s 的任意位置插入 B B B 字符。

问是否可以进行若干次操作后将 s s s 变为 t t t

解决

考虑动态规划做法,时间复杂度 O ( l s × l t ) O(l_s \times l_t) O(ls×lt)

一个动态规划数组 f f f f i , j \mathit{f}_{i,j} fi,j 表示 s i s_i si t j t_j tj 是否能匹配。

动态规划分成两个阶段解决。

  1. 初始化:

f 0 , 0 = 1 \mathit{f}_{0,0}=1 f0,0=1(这个前往别忘)

{ f i , 0 = f i , 0 ∣ f i − 1 , 0 s i = A f 0 , i = f 0 , i ∣ f 0 , i − 1 t i = B \begin{cases}\mathit{f}_{i,0}=\mathit{f}_{i,0}|\mathit{f}_{i-1,0}&s_i=A\\\mathit{f}_{0,i}=\mathit{f}_{0,i}|\mathit{f}_{0,i-1}&t_i=B\end{cases} {fi,0=fi,0fi1,0f0,i=f0,if0,i1si=Ati=B

  1. 动态规划:

f i , j = { f i , j ∣ f i − 1 , j s i = A f i , l ∣ f i , l − 1 t i = B f i , j ∣ f i − 1 , j − 1 s i = t j \mathit{f}_{i,j}=\begin{cases}\mathit{f}_{i,j}|\mathit{f}_{i-1,j}&s_i=A\\\mathit{f}_{i,l}|\mathit{f}_{i,l-1}&t_i=B\\\mathit{f}_{i,j}|\mathit{f}_{i-1,j-1}&s_i=t_j\end{cases} fi,j= fi,jfi1,jfi,lfi,l1fi,jfi1,j1si=Ati=Bsi=tj

最后判断 f l s , l t \mathit{f}_{l_s,l_t} fls,lt 是否为真即可。

代码

#include<bits/stdc++.h>
using namespace std;
string s,t;
bool f[1010][1010];
int main()
{
    cin>>s>>t,f[0][0]=1,s='0'+s,t='0'+t;
    for(int i=1;i<s.size();i++) if(s[i]=='A') f[i][0]=f[i][0]|f[i-1][0];
    for(int i=1;i<t.size();i++) if(t[i]=='B') f[0][i]=f[0][i]|f[0][i-1];
    for(int i=1;i<s.size();i++)
    {
        for(int j=1;j<t.size();j++)
        {
            if(s[i]=='A') f[i][j]=f[i][j]|f[i-1][j];
            if(t[j]=='B') f[i][j]=f[i][j]|f[i][j-1];
            if(s[i]==t[j]) f[i][j]=f[i][j]|f[i-1][j-1];
        }
    }
    if(f[s.size()-1][t.size()-1]) cout<<"YES";
    else cout<<"NO";
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值