zoukankan      html  css  js  c++  java
  • 删括号

    题目链接:https://ac.nowcoder.com/acm/problem/21303

     思路:

    • 状态表示
      • dp[i][j][k]:s1的前i个字符通过删除掉k(删除的左括号数 - 删除的右括号数)后,能与s2的前j个字符匹配
    • 状态属性
      • 为bool类型,最终答案是dp[len1][len2][0]的真值,代表s1可以通过删除一些括号对后,能与s2匹配
    • 状态计算
      • 所以说在状态dp[i][j][k]=true的情况下,对于两个串的下一个字符,只有以下四种情况

      • 对于第一种情况,可以推出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;
    typedef long long ll;
    const ll N = 110;
    
    int main() {
        string s1, s2;    cin >> s1 >> s2;
        s1 = ' ' + s1;    s2 = ' ' + s2;
        ll len1 = s1.size(), len2 = s2.size();
        bool dp[N][N][N];
        memset(dp, false, sizeof(dp));
        dp[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(dp[i][j][k]) {
                       if(!k && s1[i + 1] == s2[j + 1]) 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";
        else cout << "Impossible";
        return 0;
    }
    

      

  • 相关阅读:
    Codeforces Round #613 选讲
    Codeforces Round #612 选讲
    Codeforces917E
    一道题20
    LOJ#2244. 「NOI2014」起床困难综合症
    求欧拉回路
    *LOJ#2134. 「NOI2015」小园丁与老司机
    vim操作命令
    常见问题解决
    CentOS7下如何修改mysql的数据目录
  • 原文地址:https://www.cnblogs.com/ACM-Epoch/p/14385422.html
Copyright © 2011-2022 走看看