思路:
在思考这题时发现此题和编辑距离题目十分相似。
编辑距离
对于本题题目的状态设置看完题解后感觉十分巧妙,在原有二维基础上加了个记录删除’(‘括号数来进行状态转移。
状态设置:布尔类型(bool)f(i,j,k)表示s串删除进行删除操作后,可以与t串匹配,删除的左括号与右括号之差为k。
也就说明当k为0时删除的是合法序列。
那么状态如何转移呢:
不难发现在dp[i][j][k]合法的情况下,如果此时 s[i]=t[i]且k=0 那么说明dp[i+1][j+1][0] 也是合法的。
而后对于s串往后加了一个字符串讨论,如果加了一个’('情况下,那么在删除一个’(‘后依旧可以和t串匹配即 dp[i+1][j][k+1]=true 如果为’)'则需要删除此字符串才能与t串匹配这时需要寻找dp[i][j][k>0]情况下是否有合法的,然后进行状态转移,即dp[i][j][k-1]=true。
#include<iostream>
#include<algorithm>
#include<string>
#include <string.h>
using namespace std;
const int N = 110;
char s[N], t[N];
bool f[N][N][N/2];
int main()
{
cin >> s+1>> t+1;
int len1 = strlen(s + 1);
int len2 = strlen(t + 1);
f[0][0][0] = true;
for(int i=0;i<=len1;i++)
for(int j=0;j<=len2;j++)
for (int k = 0; k <=len1 / 2; k++)
{
if (f[i][j][k])
{
if (k == 0 && s[i + 1] == t[j + 1]) f[i + 1][j + 1][0] = true;
if (s[i + 1] == '(') f[i + 1][j][k + 1] = true;
else if (k > 0)
f[i + 1][j][k - 1] = true;
}
}
if (f[len1][len2][0]) puts("Possible");
else puts("Impossible");
return 0;
}
在这里要注意:下标要从0开始因为第一个括号也要算进去,也就是对于t没有字符的情况下s要删一个’(‘可以和t一样,即dp[1][0][1]=true(处理边界) (如果不处理会被特殊情况卡,我在这被卡了好久)
()(((())))
(((())))
正确答案:Possible