abc310D 帶限制的分組方案數

chenfy27發表於2024-03-27

將n個人分成T組,有m條限制條件,第i個條件為{a[i],b[i]},表示a[i]與b[i]不能分到同一組,問總共有多少種可行的分組方案?
1<=T<=n<=10

由於最多隻有10人,直接爆搜也能過,可以再加個剪枝:如果剩下人每人單獨一組都不夠T組則不可行。另外,為了去重,可以按編號從小到大的順序,依次考慮每個人,要麼加到已有的組裡,要麼自成一組。

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const ll inf = 1e18;
#define rep(i,a,b) for(ll i=a; i<=b; i++)
#define per(i,a,b) for(ll i=b; i>=a; i--)
////////////////////////////////////////////////////
ll n, T, m, ans;
set<ll> g[15];
set<pair<ll,ll>> forbid;
void dfs(ll x, ll t) {
    if (x > n) {
        if (t == T) {
            ans += 1;
        }
        return;
    }
    if (t > T) {
        return;
    }
    if (n-x+1+t < T) {
        return;
    }
    rep(i,1,t) {
        int ok = 1;
        for (auto i : g[i]) {
            ll j = x;
            if (i > j) swap(i, j);
            if (forbid.count({i,j}))
                ok = 0;
        }
        if (ok) {
            g[i].insert(x);
            dfs(x+1, t);
            g[i].erase(x);
        }
    }
    g[t+1].insert(x);
    dfs(x+1, t+1);
    g[t+1].erase(x);
}
void solve() {
    cin >> n >> T >> m;
    rep(i,1,m) {
        ll a, b;
        cin >> a >> b;
        if (a > b) swap(a, b);
        forbid.insert({a,b});
    }
    dfs(1, 0);
    cout << ans << "\n";
}
////////////////////////////////////////////////////
int main() {
    int t = 1;
    while (t--) solve();
    return 0;
}
int myinit = []() {
    cin.tie(0)->sync_with_stdio(0);
    return 0;
}();

相關文章