删括号

链接:https://ac.nowcoder.com/acm/problem/21303
来源:牛客网

题目描述

给你一个合法的括号序列s1,每次你可以删除一个"()"
你可以删除0个或者多个"()"
求能否删成另一个括号序列s2

输入描述:

第一行输入一个字符串s (2 ≤ |s| ≤ 100)
第二行输入一个字符串t (2 ≤ |t| ≤ 100 )

输出描述:

如果可以输出"Possible"
否则输出"Impossible"
思路:

设置三维dp[i][j][k],二维感觉不够;
dp[i][j][k]表示s1[i]和s2[j]位置在k = 删掉的'('数 - 删掉的')'数时可否匹配


第一种情况可以推出dp[i+1][j+1][k]=true或dp[i+1][j][k+1]=true;
第二种情况可以推出dp[i+1][j][k+1]=true;
第三种情况可以推出dp[i+1][j+1][k]=true或dp[i+1][j][k-1]=true;
第四种情况可以推出dp[i+1][j][k-1]=true;
综合一下就是如果后一个字符相等且k=0,那么dp[i+1][j+1][0]=true,
然后如果s的后一个字符是左括号,那么dp[i+1][j][k+1]=true,如果都不满足,并且k!=0,那么dp[i+1][j][k-1]=true.

#include<bits/stdc++.h>
using namespace std;
int dp[110][110][55];
string s1, s2;
int main(){
    cin >> s1>> s2;
    int len1, len2;
    len1 = s1.length();
    len2 = s2.length();
    memset(dp, 0, sizeof(dp));
    dp[0][0][0] = 1;
    for (int i = 0; i < len1; i++)
        for(int j = 0; j <= i; j++)
            for(int k = 0; k <len1/2+1; k++){
                if(dp[i][j][k]){
                    if(s1[i+1] == s2[j+1] && k==0)
                        dp[i+1][j+1][k] = 1;
                    if (s1[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;
    system("pause");
    return 0;
}
参考:
https://yzq2000.blog.csdn.net/article/details/90709357
https://www.cnblogs.com/letlifestop/p/10963719.html
cnblogs.com/MekakuCityActor/p/10747753.html
https://ac.nowcoder.com/acm/problem/blogs/21303

原文地址:https://www.cnblogs.com/Aliencxl/p/11943859.html