P8256字符串 题解

传送门

考虑DP

记状态 fi,j,st,en 表示现在枚举到第 i 个字符,匹配了 j 个字符,要在前面删 st 个字符,在后面删 en 个字符的方案数

不难发现 fn+1,m,0,0=1

状态转移有

si= 时,

fi,j,st,en=fi+1,j,st1,en+fi+1,j,st,en1

si=0/1 时,

fi,j,st,en=fi+1,j,st,en+1

en=0j=0fi,0,st,0+=fi+1,0,st+1,0

j!=msi=tj+1en=0fi,j,st,0+=fi+1,j+1,st,0

考虑优化:

因为可以通过 i,j,st 推断出 en 所以 en 可以不要,只记三个状态 fi,j,st

注意:当想思路清晰一些时,用记忆化搜索会比 DP 更好

上代码:

#include<bits/stdc++.h>
using namespace std;
const int N=405;
const int mod=1e9+7;
int T,n,m,len;
char s[N],t[N];
int f[N][N][N];
int dfs(int wz,int gs,int st,int en)
{
if(wz>n) return gs==m&&!st&&!en;
if(f[wz][gs][st]!=-1) return f[wz][gs][st];
long long res=0;
if(s[wz]=='-')
{
if(st) res=(res+dfs(wz+1,gs,st-1,en))%mod;
if(en) res=(res+dfs(wz+1,gs,st,en-1))%mod;
}
else
{
res=dfs(wz+1,gs,st,en+1)%mod;
if(!gs&&!en) res=(res+dfs(wz+1,0,st+1,0))%mod;
if(gs!=m&&s[wz]==t[gs+1]&&!en) res=(res+dfs(wz+1,gs+1,st,0))%mod;
}
return f[wz][gs][st]=res%mod;
}
int main()
{
scanf("%d",&T);
while(T--)
{
memset(f,-1,sizeof f);
scanf("%d %d %s %s",&n,&m,s+1,t+1);
len=0;
printf("%d\n",dfs(1,0,0,0));
}
return 0;
}

后记:真唐吧,两小时想不出这道题

posted @   傻阙的缺  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示