TopCoder SRM 727 简要题解

OnlySanta

分类讨论。

#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;

template <typename T> inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}

template <typename T> inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}

class OnlySanta {
public:
  inline bool Check(string s, string t) {
    int x = 0;
    for (int i = 0; i < s.length(); ++i) {
      if (s[i] == t[x]) {
        ++x;
        if (x == t.length()) {
          return true;
        }
      }
    }
    return false;
  }

  string solve(string S) {
    S += "TA";
    if (Check(S, "SANTA")) {
      return S;
    }
    if (!Check(S, "N")) {
      return "SAN" + S;
    }
    for (int i = S.length() - 1; ~i; --i) {
      if (S[i] == 'N') {
        return S.substr(0, i) + "SA" + S.substr(i, S.length() - i);
      }
    }
  }
};

Subrectangle

枚举每行黑白的个数,然后贪心就好了。

#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;

template <typename T> inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}

template <typename T> inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}

class Subrectangle {
public:
  int minMissed(string S) {
    int n = S.length(), ans = 1 << 30, beg = 0, end = n;
    while (beg < n && S[beg] == '.') {
      ++beg;
    }
    if (beg == n) {
      return 1;
    }
    while (S[end - 1] == '.') {
      --end;
    }
    for (int b = 1; b <= n; ++b) {
      for (int w = 0; w <= n; ++w) {
        bool flg = true;
        int ret = 0, cur;
        for (int i = beg; i < end; ) {
          if (!w && S[i] == '.') {
            flg = false;
            break;
          }
          cur = b;
          while (cur && i < n && S[i] == '#') {
            --cur, ++i;
          }
          ret += cur;
          if (i >= end) {
            break;
          }
          cur = w;
          while (cur && i < n && S[i] == '.') {
            --cur, ++i;
          }
          ret += cur;
        }
        if (flg) {
          int wid = b + w;
          if (beg % wid > w) {
            ret += b + w - beg % wid;
          }
          ret += (wid - (ret + n) % wid) % wid;
          CheckMin(ans, ret);
        }
      }
    }
    return ans;
  }
};

DoubleLive

经典套路,将贡献拆成枚举一个熊,一个人,一个熊或者人产生贡献,然后分类讨论一下就可以 O(n2) DP了。

#include <bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define mp make_pair
#define pb push_back
#define Debug(...) fprintf(stderr, __VA_ARGS__)

typedef long long LL;
typedef long double LD;
typedef unsigned int uint;
typedef pair <int, int> pii;
typedef unsigned long long uLL;

template <typename T> inline bool CheckMax(T &a, const T &b) {
  return a < b ? a = b, true : false;
}

template <typename T> inline bool CheckMin(T &a, const T &b) {
  return a > b ? a = b, true : false;
}

const int mod = 1e9 + 7;

int f[2005][4005][3], inv[6005];

class DoubleLive {
public:
  int findEV(int B, int H, int T) {
    int ans = 0;
    inv[0] = inv[1] = 1;
    for (int i = 2; i <= (B << 1) + H; ++i) {
      inv[i] = 1LL * (mod - mod / i) * inv[mod % i] % mod;
    }
    memset(f, 0, sizeof f);
    f[B - 1][H - 1][1] = B * H + B * H;
    for (int tim = 0; tim < T; ++tim) {
      for (int i = 0; i < B; ++i) {
        for (int k = 0; k < 2; ++k) {
          int j = ((B - 1) * 2 + H - 1 + 1) - tim - i * 2 - k;
          if (j < 0 || j > B + H || !f[i][j][k]) {
            continue;
          }
          int tot = i + j + 2;
          if (i) {
            f[i - 1][j + 1][k] = (1LL * f[i][j][k] * i % mod * inv[tot] + f[i - 1][j + 1][k]) % mod;
          }
          if (j) {
            f[i][j - 1][k] = (1LL * f[i][j][k] * j % mod * inv[tot] + f[i][j - 1][k]) % mod;
          }
          if (k) {
            f[i][j][k - 1] = (1LL * f[i][j][k] * inv[tot] + f[i][j][k - 1]) % mod;
          }
        }
      }
    }
    for (int i = 0; i < B; ++i) {
      for (int k = 0; k < 2; ++k) {
        int j = ((B - 1) * 2 + H - 1 + 1) - T - i * 2 - k;
        if (j < 0 || j > B + H || !f[i][j][k]) {
          continue;
        }
        ans = (ans + f[i][j][k]) % mod;
      }
    }
    if (H >= 2) {
    memset(f, 0, sizeof f);
    f[B - 1][H - 2][1] = 1LL * B * H * (H - 1) % mod;
    for (int tim = 0; tim < T; ++tim) {
      for (int i = 0; i < B; ++i) {
        for (int k = 0; k < 2; ++k) {
          int j = ((B - 1) * 2 + H - 2 + 1) - tim - i * 2 - k;
          if (j < 0 || j > B + H || !f[i][j][k]) {
            continue;
          }
          int tot = i + j + 3;
          if (i) {
            f[i - 1][j + 1][k] = (1LL * f[i][j][k] * i % mod * inv[tot] + f[i - 1][j + 1][k]) % mod;
          }
          if (j) {
            f[i][j - 1][k] = (1LL * f[i][j][k] * j % mod * inv[tot] + f[i][j - 1][k]) % mod;
          }
          if (k) {
            f[i][j][k - 1] = (1LL * f[i][j][k] * inv[tot] + f[i][j][k - 1]) % mod;
          }
        }
      }
    }
    for (int i = 0; i < B; ++i) {
      for (int k = 0; k < 2; ++k) {
        int j = ((B - 1) * 2 + H - 2 + 1) - T - i * 2 - k;
        if (j < 0 || j > B + H || !f[i][j][k]) {
          continue;
        }
        ans = (ans + f[i][j][k]) % mod;
      }
    }
    }
    if (B >= 2) {
    memset(f, 0, sizeof f);
    f[B - 2][H - 1][2] = 1LL * B * (B - 1) * H % mod;
    for (int tim = 0; tim < T; ++tim) {
      for (int i = 0; i < B - 1; ++i) {
        for (int k = 0; k < 3; ++k) {
          int j = ((B - 2) * 2 + H - 1 + 2) - tim - i * 2 - k;
          if (j < 0 || j > B + H || !f[i][j][k]) {
            continue;
          }
          int tot = i + j + 3;
          if (i) {
            f[i - 1][j + 1][k] = (1LL * f[i][j][k] * i % mod * inv[tot] + f[i - 1][j + 1][k]) % mod;
          }
          if (j) {
            f[i][j - 1][k] = (1LL * f[i][j][k] * j % mod * inv[tot] + f[i][j - 1][k]) % mod;
          }
          if (k) {
            f[i][j][k - 1] = (1LL * f[i][j][k] * k * inv[tot] + f[i][j][k - 1]) % mod;
          }
        }
      }
    }
    for (int i = 0; i < B; ++i) {
      for (int k = 0; k < 3; ++k) {
        int j = ((B - 2) * 2 + H - 1 + 2) - T - i * 2 - k;
        if (j < 0 || j > B + H || !f[i][j][k]) {
          continue;
        }
        ans = (ans + f[i][j][k]) % mod;
      }
    }
    }
    return ans;
  }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值