[ABC310] D - Peaceful Teams

[Q] https://atcoder.jp/contests/abc310/tasks/abc310_d

地獄の業火に90分焼かれました。

考察
こちら間違いルート。
・10!=3628800 なので、N!*100くらいならいけそう。
・とりあえずチーム人数の分け方は求まりそう。5人を2チームにわけるのは(1, 4)と(2, 3)の2通りだなと思うが、この道はTLEルート。間違い。
・このあと、next_permutation()で探索かと思うが、これが、あっこの沼、深いッ!ボボボボボボ!!
・combination分減らすもTLE。

正解ルートはこっち。
---------------解説---------------
・1人ずつ処理する。処理は2パターンのみ。
1. 既存チームに加える
2. チームを新設する
これで、N人見終わったときにTチーム存在すれば正解パターンに加算。

実装

int main() {
  cincout();
  ll ans = 0;
  ll N, T, M;
  cin >> N >> T >> M;
  vector<ll> ng(N, 0);
  rep(i, M){
    ll a, b;
    cin >> a >> b;
    --a, --b;
    ng[b] |= (1 << a);
  }
  // 1人ずつ処理する。
  // 既存チームに加えられるなら入れる。
  // Tチームに至っていないなら新設する。
  vector<ll> teams(T, 0);
  function<void(ll, ll)> dfs = [&](ll cur, ll teamcnt) {
    if (cur == N){
      if (teamcnt == T) ++ans;
      return;
    }
    // 既存チームに加える
    rep(i, teamcnt) {
      if (teams[i] & ng[cur]) continue;
      teams[i] |= (1 << cur);
      dfs(cur + 1, teamcnt);
      teams[i] &= ~(1 << cur);
    }
    // 新設する
    if (teamcnt < T) {
      teams[teamcnt] |= (1 << cur);
      dfs(cur + 1, teamcnt + 1);
      teams[teamcnt] &= ~(1 << cur);
    }
  };
  dfs(0, 0);
  cout << ans << endl;
}

https://atcoder.jp/contests/abc310/submissions/43648573


いいなと思ったら応援しよう!