NC21303 删括号 问删除括号对,能否将s转变成 t 线性DP 栈

 链接: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

备注:

子任务1: |s| <= 10
子任务2: |s| <= 20
子任务3: 无限制

分析

序号递推看是否满足条件

dp[i][j] 表示s前i位,删除若干次后能不能变成 t

1.如果两者末位相同,说明删除末位可以转变成 t

2.如果最后一个是 ) ,删除最后的有序括号序列,可以转变成 t

#include<bits/stdc++.h>
using namespace std;
char s[105],t[105];
int f[105][105];
int main()
{
    f[0][0] = 1;
    cin>>s>>t;
    int len1 = strlen(s),len2 = strlen(t);
    for(int i = 1;i<=len1;i++) {
        for(int j = 0;j<=len2;j++) {
            if(s[i-1] == t[j-1]) f[i][j] |= f[i-1][j-1];
            if(s[i-1] == ')') {
                int l = 1,r = i - 1;
                while(l) {
                    if(s[r-1] == ')') l ++ ;
                    else l -- ;
                    r -- ;
                }
                f[i][j] |= f[r][j];
            }
        }
    }
    if(f[len1][len2]) cout<<"Possible"<<endl;
    else cout<<"Impossible"<<endl;
}

 

posted @ 2022-08-30 21:37  er007  阅读(31)  评论(0编辑  收藏  举报