萌新状压DP 10pts 过样例求助
查看原帖
萌新状压DP 10pts 过样例求助
610557
shinzanmonoszm 妹妹楼主2023/5/21 18:12
#include<iostream>
#include<algorithm>
#include<cassert>
const int sz = 25;
using ll = long long;
const int mod = 1e8 + 7;
ll f[1 << 20][sz], dpp;
int bet[sz][sz];
struct point {
    int x, y;
    point operator-(const point &a) const {
        return point{x - a.x, y - a.y};
    }
} pts[sz];
bool isline(point a, point b, point c) {
    point ac = c - a, ab = b - a, bc = c - b;
    if (ac.x * ab.y == ac.y * ab.x && ab.x * bc.x >= 0 && ab.y * bc.y >= 0) return true;
    return false;
}
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int n, maxn;
    std::cin >> n;
    maxn = 1 << n;
    for (int i = 0; i < n; i++)
        std::cin >> pts[i].x >> pts[i].y;
    for (int i = 0; i < n; i++) {
        for (int j = i + 1; j < n; j++) {
            for (int k = 0; k < n; k++) {
                if (k == i || k == j) continue;
                if (isline(pts[i], pts[k], pts[j])) bet[i][j] |= 1 << k;
            }
            bet[j][i] = bet[i][j];
        }
    }
    for (int i = 0; i < n; i++) f[1 << i][i] = 1;
    for (int i = 0; i < maxn; i++) {
        for (int j = 0; j < n; j++) {
            if ((i & (1 << j)) == 0) continue;
            for (int k = 0; k < n; k++) {
                if (i & (1 << k)) continue;
                if ((i ^ maxn) & bet[j][k]) continue;
                f[i | (1 << k)][k] = (f[i][j] + f[i | (1 << k)][k]) % mod;
            }
        }
    }
    ll ans = 0;
    for (int i = 0; i < maxn; i++)
        if (__builtin_popcount(i) >= 4)
            for (int j = 0; j < n; j++)
                ans = (ans + f[i][j]) % mod;
    std::cout << ans << "\n";
    return 0;
}
2023/5/21 18:12
加载中...