HDU - 6170 Two strings dp
2017-08-23 13:37
351 查看
原题链接
HDU 6170分析
输入两个字符串s,t。定义状态dp[i][j]表示s[1...i]和t[1...j]是否可以匹配成功。如果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]
但是如果这样写的话时间复杂度最坏可以达到O(N3)。主要是因为红色部分状态转移代价太大。注意到红色部分其实就是个后缀的关系,只需要维护一个sum数组,sum[i][j]=dp[k−1][j] || dp[k][j] || dp[k+1][j] || … || dp[i][j],其中s[k...i]是一段连续且相等的字符。这样一来红色部分就可以写成dp[i][j]=sum[i−1][j−2] || dp[i][j−2]了。更新sum[i][j]的代价是O(1)的,因为sum[i][j]=sum[i−1][j] || dp[i][j]。总的复杂度是O(N2)。
代码
#include <bits/stdc++.h> using namespace std; const int N = 2505; char s , t ; int lens, lent; bool dp ; bool sum ; 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; }
相关文章推荐
- HDU 6170 && 2017 多校训练:Two strings(DP)
- HDU 6170(Two strings-DP)
- HDU 6170----Two strings(DP)
- hdu 6170 Two strings dp
- 2017多校第9场 HDU 6170 Two strings DP
- Hdu 6170 Two strings【思维+Dp】
- 2017多校第9场 HDU 6170 Two strings DP
- hdu 6170 Two strings dp
- HDU 6170 Two strings dp || 正则
- 2017多校联合第9场1010 Two String/hdu 6170(正则表达式/dp)
- 2017多校9 Two string hdu 6170 dp
- Two strings HDU - 6170 递推
- HDU 5791 Two (DP)
- hdu 6170 正则表达式 dp
- HDU 6170 递推 DP,思考状态的递进
- 51nod 1202 子序列个数 (子序列套路dp)&& HDU 5791 Two (两串求相同子序列)
- hdu 6170 正则表达式 dp
- HDU 5791 Two ( DP )
- HDU-5791-TWO-DP
- hdu 6170 正则表达式 dp