https://blog.youkuaiyun.com/优快云jiangshan/article/details/86239183?tdsourcetag=s_pctim_aiomsg
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
int n,m;
int dis[18][18],dis1[18][18];
int a[18][10005];
int dp[18][18][(1<<16)+5];
int inf=1e9+10;
int main() {
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&a[i][j]);
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
dis[i][j]=dis1[i][j]=inf;
if(i!=j)
{
for(int k=0;k<m;k++)
dis[i][j]=min(dis[i][j],abs(a[i][k]-a[j][k]));
}
for(int k=1;k<m;k++)
dis1[i][j]=min(dis1[i][j],abs(a[i][k-1]-a[j][k]));
//cout<<dis[i][j]<<endl;
}
int len=1<<n;
memset(dp,0,sizeof(dp));
for(int i=0;i<n;i++)
{
dp[i][i][1<<i]=dis[i][i];
}
for(int i=1;i<len-1;i++)
{
for(int s=0;s<n;s++)
{
if(((i>>s)&1)!=0)
for(int e=0;e<n;e++)
{
if(((i>>e)&1)!=0)
for(int cur=0;cur<n;cur++)
{
if(((i>>cur)&1)==0)
{
dp[s][cur][i|(1<<cur)]=max(dp[s][cur][i|(1<<cur)],min(dp[s][e][i],dis[e][cur]));
}
}
}
}
}
int ans=0;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
{
ans=max(ans,min(dp[i][j][len-1],dis1[i][j]));
}
printf("%d\n",ans);
}
return 0;
}