QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#393662#8554. Bot Friendshos_lyricTL 17ms12028kbC++144.9kb2024-04-19 03:11:552024-04-19 03:11:56

Judging History

你现在查看的是最新测评结果

  • [2024-04-19 03:11:56]
  • 评测
  • 测评结果:TL
  • 用时:17ms
  • 内存:12028kb
  • [2024-04-19 03:11:55]
  • 提交

answer

#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

using Int = long long;

template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")


int brute(const string &S) {
  const int N = S.size();
  vector<int> dp(1 << (2*N+1), -1);
  dp[0] = 0;
  for (int p = 0; p < 1 << (2*N+1); ++p) if (~dp[p]) {
    // bot i+0.5
    for (int i = 0; i < N; ++i) if (!(p & 1 << (2*i+1))) {
      if (S[i] == '?' || S[i] == '<') {
        for (int j = i; ; --j) {
          assert(j >= 0);
          if (!(p & 1 << (2*j))) {
            chmax(dp[p | 1 << (2*i+1) | 1 << (2*j)], dp[p] + ((j != i) ? 1 : 0));
            break;
          }
        }
      }
      if (S[i] == '?' || S[i] == '>') {
        for (int j = i + 1; ; ++j) {
          assert(j <= N);
          if (!(p & 1 << (2*j))) {
            chmax(dp[p | 1 << (2*i+1) | 1 << (2*j)], dp[p] + ((j != i+1) ? 1 : 0));
            break;
          }
        }
      }
    }
  }
  return *max_element(dp.begin(), dp.end());
}

int solve(const string &S) {
  const int N = S.size();
  // pos, height, last (+: 0, -: 1)
  int dp[2][5010][2];
  memset(dp, ~0, sizeof(dp));
  dp[0][0][1] = 0;
  for (int i = 0; i < N; ++i) {
    auto crt = dp[i & 1];
    auto nxt = dp[(i + 1) & 1];
    const int lim = min(i, N - i);
    for (int x = 0; x <= lim + 1; ++x) for (int s = 0; s < 2; ++s) nxt[x][s] = -1;
    for (int x = 0; x <= lim; ++x) for (int s = 0; s < 2; ++s) if (~crt[x][s]) {
      // discard
      if (x == 0) {
        chmax(nxt[x][s], crt[x][s]);
      }
      // +
      if (S[i] == '?' || S[i] == '>') {
        chmax(nxt[x + 1][0], crt[x][s] + 1);
      }
      // -
      if (S[i] == '?' || S[i] == '<') {
        if (s == 0) {
          // yama: choose [-1, +1]
          for (int y = max(x - 1, 0); y <= x + 1; ++y) {
            chmax(nxt[y][1], crt[x][s]);
          }
        } else {
          if (x) {
            chmax(nxt[x - 1][1], crt[x][s] + 1);
          }
        }
      }
    }
  }
  int ans = -1;
  for (int s = 0; s < 2; ++s) {
    chmax(ans, dp[N & 1][0][s]);
  }
  return ans;
}

void exper() {
  for (int n = 1; n <= 10; ++n) {
    for (int p = 0; p < 1 << n; ++p) {
      string s(n, '?');
      for (int i = 0; i < n; ++i) s[i] = "<>"[p >> i & 1];
      const int brt = brute(s);
      assert(brt <= n - 1);
      if (brt == n - 1) {
        cerr << s << " " << brt << endl;
      }
      cout << s << " " << brt << endl;
      
      vector<int> dp(n + 1, 0);
      dp[0] = 0;
      for (int i = 0; i < n; ++i) {
        chmax(dp[i + 1], dp[i]);
        for (int j = i + 1; j <= n; ++j) {
          /*
          const int half = (j - i) / 2;
          if (s.substr(i, half) == string(half, '>') &&
              s.substr(j - half, half) == string(half, '<')) {
            chmax(dp[j], dp[i] + (j - i - 1));
          }
          */
          int yama = 0;
          int can = 1 << 0;
          for (int k = i; k < j; ++k) {
            if (i < k && s[k - 1] == '>' && s[k] == '<') {
              // choose [-1, +1]
              ++yama;
              can = can >> 1 | can | can << 1;
            }
            can = (s[k] == '>') ? (can << 1) : (can >> 1);
          }
          if (can >> 0 & 1) {
            chmax(dp[j], dp[i] + (j - i - yama));
          }
        }
      }
      if (brt != dp[n]) {
        cerr << s << " " << brt << " " << dp << endl;
      }
      assert(brt == dp[n]);
    }
    cerr << "DONE n = " << n << endl;
  }
}

int main() {
  // exper(); return 0;
  
  char buf[5010];
  for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
    scanf("%s", buf);
    const int brt = brute(buf);
    printf("%d\n", brt);
  }
#ifndef LOCAL
  break;
#endif
  }
  return 0;
}

详细

Test #1:

score: 100
Accepted
time: 17ms
memory: 12028kb

input:

10
?>?
>?<
??<?
?><?<
??????
>?<?<>?<?<
?><???><><
??>>><><??
<>>?>>?>?>
<?<>>??<?>

output:

2
2
3
4
5
8
7
8
5
6

result:

ok 10 numbers

Test #2:

score: -100
Time Limit Exceeded

input:

100000
>?<?<>?<?<
?><???><><
??>>><><??
<>>?>>?>?>
<?<>>??<?>
>><>><<<<<
>?>?>?<<>>
?><?<<?<><
???><>?>?>
<??>?<<><?
??>><?<>>>
<><><?<>>?
?>>?>???><
?<?><?<<>?
>>><?<??><
><><<>?>?<
>?><>><<<?
>??>?><?<>
?????<><?>
<><<?<<>?<
><?>>?>?>?
?><><<<>>?
?<>?<>?<<<
<><<<<<>>>
?>?>?><<>>
<>?<>><>?<
<<<?<>>...

output:


result: