细节dp codeforces 212C

http://codeforces.com/contest/212/problem/C

这类题目好难做啊。。

找到一个\(B\)放到序列的最前面然后枚举\(B\)前一个数的初始方向

记状态\(f[i][0/1]\)为前\(i\)个满足条件第\(i\)个方向是\(0/1\)

然后讨论一下第\(i\)个数是保持原状,还是和\(i-1\)打战

复杂度\(\mathcal O(n)\)

#include <bits/stdc++.h>
#define int long long
#define rint register int
#define fo(i, n) for(rint i = 1; i <= (n); i ++)
#define out(x) cerr << #x << " = " << x << "\n"
#define type(x) __typeof((x).begin())
#define foreach(it, x) for(type(x) it = (x).begin(); it != (x).end(); ++ it)
  using namespace std;
// by piano
template<typename tp> inline void read(tp &x) {
  x = 0;char c = getchar(); bool f = 0;
  for(; c < '0' || c > '9'; f |= (c == '-'), c = getchar());
  for(; c >= '0' && c <= '9'; x = (x << 3) + (x << 1) + c - '0', c = getchar());
  if(f) x = -x;
}
const int N = 111;
int dp[N][2], n;
char str[N];
inline int gao(string str, int x) {
  memset(dp, 0, sizeof dp);
  dp[0][x] = 1;
  for(int i = 1; i <= n; i ++) {
    if(!str[i]) {
      dp[i][0] = dp[i - 1][0];
    }
    else {
      if(!str[i - 1]) {
        dp[i][0] = dp[i - 2][0] + dp[i - 2][1];
        dp[i][1] = dp[i - 1][0];
      }
      else {
        dp[i][1] = dp[i - 1][0] + dp[i - 1][1];
      }
    }
  }
  return dp[n][x];
}

main(void) {
  scanf("%s", str + 1);
  n = strlen(str + 1);
  fo(i, n) str[i] = str[i] == 'A';
  int pos = 0;
  for(int i = 1; i <= n; i ++)
    if(!str[i]) {
      pos = i;
      break;
    }
  if(!pos) return puts("1"), 0;
  string s = " ";
  for(int i = pos; i <= n; i ++)
    s += str[i];
  for(int i = 1; i <= pos - 1; i ++)
    s += str[i];
  cout << gao(s, 0) + gao(s, 1) << "\n";
}

猜你喜欢

转载自www.cnblogs.com/foreverpiano/p/9297649.html