预处理一下两两之间的最小值, 然后直接dp。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 1e4 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, m; int Mat[16][N]; int go[16][16]; int go2[16][16]; int dp[1 << 16][16]; int main() { scanf("%d%d", &n, &m); for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) scanf("%d", &Mat[i][j]); int ans = 0; if(n == 1) { ans = inf; for(int i = 0; i < m - 1; i++) ans = min(ans, abs(Mat[0][i] - Mat[0][i + 1])); printf("%d ", ans); return 0; } for(int i = 0; i < n; i++) { for(int j = 0; j < n; j++) { if(i == j) continue; go[i][j] = go2[i][j] = inf; for(int k = 0; k < m; k++) go[i][j] = min(go[i][j], abs(Mat[i][k] - Mat[j][k])); for(int k = 0; k < m - 1; k++) { go2[i][j] = min(go2[i][j], abs(Mat[i][k] - Mat[j][k + 1])); } } } for(int start = 0; start < n; start++) { memset(dp, -1, sizeof(dp)); dp[1 << start][start] = inf; for(int S = 1; S < (1 << n); S++) { for(int i = 0; i < n; i++) { if(dp[S][i] < 0) continue; for(int j = 0; j < n; j++) { if(S >> j & 1) continue; dp[S|(1<<j)][j] = max(dp[S|(1<<j)][j], min(go[i][j], dp[S][i])); } } } for(int i = 0; i < n; i++) ans = max(ans, min(go2[i][start], dp[(1<<n)-1][i])); } printf("%d ", ans); return 0; } /* */