题目链接:https://ac.nowcoder.com/acm/problem/21303
题目描述:
给你一个合法的括号序列s1,每次你可以删除一个"()"
你可以删除0个或者多个"()"
求能否删成另一个括号序列s2
输入描述:
第一行输入一个字符串s (2 ≤ |s| ≤ 100)
第二行输入一个字符串t (2 ≤ |t| ≤ 100 )
输出描述:
如果可以输出"Possible"
否则输出"Impossible"
示例1:
输入:
(())
()
输出:
Possible
示例2:
输入:
()
()
输出:
Possible
示例3:
输入:
(()()())
((()))
输出:
Impossible
示例4:
输入:
((())((())())())
(()(())())
输出:
Possible
示例5:
输入:
((())((())())())
((()()()()()))
输出:
Impossible
思路:
对于这种判断能否转化的问题,基本都用dp[i][j][k]1/0的办法来判断时候匹配,由于匹配存在多种情况,本位匹配和非本位匹配。都要考虑上
k=删除的‘(’数量-删除的‘)’数量
代码:
#include<iostream>
#include<cstring>
using namespace std;
const int maxn = 105;
char s[maxn], t[maxn];
int dp[105][105][55];
int main()
{
int i, j, k;
int len1, len2;
while (cin >> s + 1 >> t + 1)
{
len1 = strlen(s + 1);
len2 = strlen(t + 1);
dp[0][0][0] = 1;
for (i = 0; i < len1; ++i)
{
for (j = 0; j <= len2; ++j)
{
for (k = 0; k <= len1 / 2; ++k)
{
if (dp[i][j][k])
{
if (!k && s[i + 1] == t[j + 1])
dp[i + 1][j + 1][0] = 1;
if (s[i + 1] == '(')
dp[i + 1][j][k + 1] = 1;
else if (k)
dp[i + 1][j][k - 1] = 1;
}
}
}
}
if (dp[len1][len2][0])
cout << "Possible" << endl;
else
cout << "Impossible" << endl;
return 0;
}
}