6170 Two strings (多校,DP,字串匹配)
阿新 • • 發佈:2018-12-24
題目描述:
題意給你兩串字串,其中'.'可以替換成任意字元,'*'表示前面一個字元可以出現任意次。
用dp來處理,用dp[i][j]來表a[i],b[j]是否匹配,這題有一個及其神奇的操作就是a*可以處理成空串,*居然可以表示出現0次,真的是無比佩服出題人的腦洞,剩下就是狀態轉移,其實都很簡單,只要細心就行,如果b[j]==a[i]或者b[j]=='.'那麼該點肯定可以匹配dp[i][j]=dp[i-1][j-1],如果b[j]=='*'那麼討論這個*的情況,第一處理成空串dp[i][j]=dp[i-2][j],第二不管這個*號,dp[i][j]=dp[i-1][j],然後考慮這個*號如果a[i]==a[i-1]的話,dp[i][j]=dp[i-1][j]||dp[i-1][j-1]。
AC程式碼:
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<cmath> #include<stack> #include<vector> #include<set> #include<queue> #include<algorithm> using namespace std; const int MAXM=2505; bool dp[MAXM][MAXM]; char s1[MAXM],s2[MAXM]; int main() { int T; scanf("%d",&T); while(T--) { scanf("%s",s1+1); scanf("%s",s2+1); memset(dp,false,sizeof(dp)); dp[0][0]=true; if (s2[2]=='*') dp[0][2]=true; int lena=strlen(s1+1); int lenb=strlen(s2+1); for (int i=1;i<=lena;i++) { for (int j=1;j<=lenb;j++) { if (s1[i]==s2[j]) dp[i][j]=dp[i-1][j-1]; if (s2[j]=='.') dp[i][j]=dp[i-1][j-1]; if (s2[j]=='*') { dp[i][j]=dp[i][j-2]|dp[i][j-1]; if (s1[i]==s1[i-1]) dp[i][j]=dp[i-1][j]|dp[i-1][j-1]; } } } if (dp[lena][lenb]) printf("yes\n"); else printf("no\n"); } return 0; }