1. 程式人生 > >Codeforces Round #459 (Div. 2)The Monster[匹配問題]

Codeforces Round #459 (Div. 2)The Monster[匹配問題]

sin bre 成了 多少 -m bits 當前 define log

題意

給一個序列,包含(,),?,?可以被當做(或者),問你這個序列有多少合法的子序列。

分析

n^2枚舉每一個子序列,暫時將每個?都當做右括號,在枚舉右端點的時候同時記錄兩個信息:當前左括號多余多少個(top),已經將多少個?變成了右括號(cnt)。
如果當前是(,top++.
如果當前是),top--.
如果當前是?,top--,cnt++;
如果top<0,我們需要判斷一下當前還有沒有之前被當做右括號的?,如果有的話,我們將其變為左括號,如果沒有的話,意味著可以跳出循環了,之後都不會再合法了。
如果任何時刻top==0,那麽意味著當前區間合法,ans++。
巧妙地貪心

代碼

#include <bits/stdc++.h>
using namespace std;

#define ll long long

char s[5050];

int main(int argc, char const *argv[])
{
    scanf("%s",s);
    int ans=0;
    for(int i=0;s[i]!='\0';++i)
    {
        int left=0,cnt=0;
        for(int j=i;s[j]!='\0';++j)
        {
            if(s[j]=='(') left++;
            if(s[j]==')') left--;
            if(s[j]=='?') left--,cnt++;
            if(left<0&&cnt) left+=2,cnt--;
            if(left==0) ans++;
            if(left<0&&!cnt) break;
        }
    }
    printf("%d\n",ans );
    return 0;
}

Codeforces Round #459 (Div. 2)The Monster[匹配問題]