http://acm.hdu.edu.cn/showproblem.php?pid=6435
给两个点集 从两集合分别挑一个点 求k维最远曼哈顿距离
枚举2^k个状态 每个状态下 第一个点集取一个最小值 第二个点集取最大值 相减后取最大值
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const ll N=0x3f3f3f3f3f3f3f3f;
ll point1[100010][10],point2[100010][10];
int pre[50];
int n1,n2,m;
void init()
{
int i;
pre[0]=1;
for(i=1;i<=30;i++) pre[i]=2*pre[i-1];
}
ll getmin(ll a,ll b)
{
if(a<b) return a;
else return b;
}
ll getmax(ll a,ll b)
{
if(a>b) return a;
else return b;
}
ll solve()
{
ll res,minn,maxx,sum;
int i,j,k;
res=-N;
for(k=0;k<pre[m];k++)
{
minn=N;
for(i=1;i<=n1;i++)
{
sum=0;
for(j=0;j<m;j++)
{
if(k&pre[j]) sum+=point1[i][j];
else sum-=point1[i][j];
}
minn=getmin(minn,sum);
}
maxx=-N;
for(i=1;i<=n2;i++)
{
sum=0;
for(j=0;j<m;j++)
{
if(k&pre[j]) sum+=point2[i][j];
else sum-=point2[i][j];
}
maxx=getmax(maxx,sum);
}
res=getmax(res,maxx-minn);
}
return res;
}
int main()
{
int t,i,j;
init();
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n1,&n2,&m);
m++;
for(i=1;i<=n1;i++)
{
for(j=0;j<m;j++) scanf("%lld",&point1[i][j]);
}
for(i=1;i<=n2;i++)
{
for(j=0;j<m;j++) scanf("%lld",&point2[i][j]);
point2[i][0]=-point2[i][0];
}
printf("%lld\n",solve());
}
return 0;
}