观察数据范围:4 ≤ N ≤ 16。
很明显,这是一道状压DP。
定义:dp[i][j]表示队尾为奶牛i,当前含奶牛的状态为j,共有多少组符合条件的队伍。
代码实现如下:
#include <bits/stdc++.h> using namespace std; #define LL long long #define rep(i, a, b) for (register int i = a; i <= b; i++) const int maxn = 20; int n, m; LL ans = 0; int a[maxn]; LL dp[maxn][2 << maxn]; int read() { int x = 0, flag = 0; char ch = ' '; while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if (ch == '-') { flag = 1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = (x << 1) + (x << 3) + ch - '0'; ch = getchar(); } return flag ? -x : x; } void write(LL x) { if (x < 0) { putchar('-'); x = -x; } if (x > 9) write(x / 10); putchar(x % 10 + '0'); } int main() { n = read(), m = read(); rep(i, 1, n) a[i] = read(); rep(i, 1, n) dp[i][1 << (i - 1)] = 1; rep(i, 1, (1 << n) - 1) { rep(j, 1, n) { if (i & (1 << (j - 1))) rep(k, 1, n) { if (!(i & (1 << (k - 1))) && abs(a[j] - a[k]) > m) dp[k][i | (1 << (k - 1))] += dp[j][i]; } } } rep(i, 1, n) ans += dp[i][(1 << n) - 1]; write(ans); return 0; }