ferinの競プロ帳

競プロについてのメモ

SRM670 div1 easy Bracket107

考えたこと

  • 括弧列で定番の+1/-1の累積和とか考えるけどよくわからないので実験する
  • 括弧列の長さがnのとき、LCSがn-1の括弧列が絶対につくれる気がする
  • 1文字をずらしていったような括弧列はLCSがn-1になるはず
  • 括弧を飛び越すようなずらし方をすれば異なる括弧列ができるし正しそう
  • 与えられた括弧列sの1文字をどこか別の場所にずらしてできる括弧列で異なるものが何種類あるか数える問題に帰着できそう
  • 全列挙してsetに突っ込んでsetの要素数を数えるとよさそう
  • 列挙するのがO(n^2)、括弧列か確かめるのにO(n)、setの操作でO(logn)で全体O(n^3logn)で投げると通る
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
typedef vector<int> VI;
typedef vector<VI> VVI;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef pair<int, int> PII;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define IN(a, b, x) (a<=x&&x<b)
#define MP make_pair
#define PB push_back
const int INF = (1LL<<30);
const ll LLINF = (1LL<<60);
const double PI = 3.14159265359;
const double EPS = 1e-12;
const int MOD = 1000000007;
//#define int ll

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

class Bracket107 {
   public:
   int yetanother(string s)
  {
    int n = s.size();
    set<string> st;
    REP(i, n) {
      string t = "";
      REP(j, n) if(i != j) t += s[j];
      FOR(j, 1, t.size()) {
        string tmp = t, in = "";
        in += s[i];
        tmp.insert(j, in);

        int now = 0;
        bool flag = true;
        REP(k, tmp.size()) {
          if(tmp[k] == '(') now++;
          else now--;
          if(now < 0) flag = false;
        }
        if(flag && now == 0) st.insert(tmp);
      }
    }

    return st.size()-1;
  }
};