删括号

链接: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
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
    string s, t;
    cin >> s >> t;
    bool dp[110][110][55] = {false};
    dp[0][0][0] = true;
    for(int i=0;i<s.size();i++)
        for(int j=0;j<t.size();j++)        
            for (int k = 0; k < s.size() / 2; k++)    //需要消除的'('
            {
                if (dp[i][j][k])
                {
                    if (!k&&s[i + 1] == t[j + 1]) dp[i + 1][j + 1][0] = true;    //
                    if (s[i + 1] == '(') dp[i + 1][j][k + 1] = true;    //如果s[i+1]是'('的话,在t字符串的前j个字符中本来只需要删除k个左括号的,所以多出的'('可以消除所以k+1
                    else dp[i + 1][j][k - 1] = true;                    //如果s[i+1]是')'的话,在t字符串中前j个字符中本来只需要删除k个'(',而出现右括号代表不需要删除此括号,所以当前只需要消除k-1个'('
                }
            }
    puts(dp[s.size()][t.size()][0] ? "Possible" : "Impossible");
}

最近才刚刚着手动态规划,所以在牛客网找了个两星题目,结果发现这道题对萌新来说不太友好,消耗了我6小时才稍微看懂一点代码,但还是看懂一知半解,不过对动态规划的大问题化小问题又有新的了解了。dp指的是状态(状态的意思还是没搞很懂,还在摸索),其次还有些问题就是该如何去拆分大问题。这是值得思考的。

解题思路:i和j分别代表字符串s和字符串t的第i和第j的前面一部分,而k代表的是需要减去的'(',意思是s减去多少个'('会和t相匹配.

原文地址:https://www.cnblogs.com/pppyyyzzz/p/11662632.html