HDU 6170 && 2017 多校訓練:Two strings(DP)
阿新 • • 發佈:2018-12-24
題意:
給你兩個字串:第一個字串只包含小寫大寫字母
第二個字串除了字母之外,還有'.'和'*',其中'.'可以當成任意一個字元,'*'表示前面那個字元可以重複若干次
當然也可以重複0次,例如a.*A可以是aaaA,可以是abbbbA等等,也可以是aA
問兩個串能不能匹配(即第二個字串某種情況下和第一個字串一模一樣)
因為長度只有2500,很好想到DP,dp[x][y]表示第二個字串長度為x,第一個字串長度為y能否完美匹配(1or0)
但是要注意的細節特別多,具體看程式碼
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int n, m, dp[2505][2505]; char str[2505], jud[2505]; int main(void) { int T, i, j; scanf("%d", &T); while(T--) { scanf("%s%s", str+1, jud+1); memset(dp, 0, sizeof(dp)); n = strlen(str+1); m = strlen(jud+1); dp[0][0] = 1; for(i=1;i<=m;i++) { if(jud[i]=='*' && i==2) dp[i][0] = 1; for(j=1;j<=n;j++) { if(jud[i]=='.') dp[i][j] = dp[i-1][j-1]; else if(jud[i]!='*') { if(jud[i]==str[j]) dp[i][j] = dp[i-1][j-1]; } else { dp[i][j] = max(dp[i-2][j], dp[i-1][j]); if((dp[i-1][j-1]==1 || (dp[i][j-1]==1)) && str[j]==str[j-1] && (str[j]==jud[i-1] || jud[i-1]=='.')) dp[i][j] = max(dp[i][j], max(dp[i][j-1], dp[i-1][j-1])); } } } if(dp[m][n]==1) printf("yes\n"); else printf("no\n"); } return 0; }