原题链接
分析
输入两个字符串
- 如果
s[i]==t[j] ||t[j] ==‘.’,则dp[i][j]=dp[i−1][j−1] - 如果
t[j] ==‘*’,分为下面两种情况。
(1)t[j−1] !=s[i] &&t[j−1] !=‘*’,此时‘*’不能匹配任何字符。所以
dp[i][j]=dp[i][j−2]
(2) 除了(1)之外的情况,‘*’可以匹配0到多个s[i] 字符。 假设s[k...i] 是一段连续且相等的字符,则dp[i][j]=dp[k−1][j−2] ||dp[k][j−2] ||dp[k+1][j−2] || … ||dp[i][j]
但是如果这样写的话时间复杂度最坏可以达到
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 2505;
char s[N], t[N];
int lens, lent;
bool dp[N][N];
bool sum[N];
int main()
{
//freopen("test.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int T;
scanf("%d", &T);
while (T--)
{
scanf("%s%s", s + 1, t + 1);
lens = strlen(s + 1);
lent = strlen(t + 1);
memset(dp, false, sizeof(dp));
memset(sum, false, sizeof(sum));
for (int i = 0; i <= lens; i++)
{
for (int j = 0; j <= lent; j++)
{
if (!i && !j)
{
dp[0][0] = true;
continue;
}
if (t[j] == s[i] || t[j] == '.')
dp[i][j] = dp[i - 1][j - 1];
else if (t[j] == '*')
{
if (t[j - 1] != s[i] && t[j - 1] != '.')
dp[i][j] = dp[i][j - 2];
else if (s[i] == s[i - 1])
dp[i][j] = sum[j - 2] || dp[i][j - 2];
else
dp[i][j] = dp[i][j - 2] || dp[i - 1][j - 2];
}
}
for (int j = 0; j <= lent; j++)
if (s[i] == s[i - 1])
sum[j] = sum[j] || dp[i][j];
else
sum[j] = dp[i][j] || dp[i - 1][j];
}
if (dp[lens][lent])
printf("yes\n");
else
printf("no\n");
}
return 0;
}