此题值得分析:
曼哈顿距离:两个点所对应的坐标差的绝对值之和。比如在一维空间:x1,x2. d=|x1-x2|,二维空间:(x1,y1),(x2,y2) d=|x1-x2|+|y1-y2| 三维空间(x1,y1,z1),(x2,y2,z2)
d=|x1-x2|+|y1-y2|+|z1-z2|,以此类推。。。
看到绝对值,我们就想到去绝对值。如果在二维空间:d=|x1-x2|+|y1-y2|
拆开:x1-x2+y1-y2, x1-x2+y2-y1, x2-x1+y1-y2, x2-x1+y2-y1 每个绝对值的里面去了有2种,有n维空间,就有2*2*2.......2=>2^n
在把上面的整理一下有:(x1+y1)+(-x2-y2) , (-x1+y1)+(x2-y1),(x1-y1)+(-x2+y2),(-x1-y1)+(x2+y2);
再看对应每个点:(x1+y1),(-x1+y1),(x1-y1),(-x1-y1)和 (x2+y2),(-x2+y2),(x2-y2),(x2+y2)
这样就可以把每个点的2^n种情况计算出来了这样就可以其他点做差,取出最大的就行了
代码:
#include<cstdio>
#include<cstring>
#include<set>
using namespace std;
multiset<int>mt[32];
multiset<int>::iterator it1,it2;
int a[60005][6];
int main()
{
int n,m,i,j,k;
int od,x,tmp,ret;
while(scanf("%d %d",&n,&m)!=EOF){
for(i=0;i<32;i++) mt[i].clear();
for(i=1;i<=n;i++){
scanf("%d",&od);
if(od==0){
for(j=0;j<m;j++)
scanf("%d",&a[i][j]);
for(j=0;j<(1<<m);j++){
tmp=0;
for( k=0;k<m;k++)
if(j&(1<<k)) tmp+=a[i][k];
else tmp-=a[i][k];
mt[j].insert(tmp);
}
}
else{
scanf("%d",&x);
for(j=0;j<(1<<m);j++){
tmp=0;
for(k=0;k<m;k++)
if(j&(1<<k)) tmp+=a[x][k];
else tmp-=a[x][k];
it1=mt[j].find(tmp);
mt[j].erase(it1);
}
}
ret=0;
for(j=0;j<(1<<m);j++){
it1=mt[j].end();
it1--;
it2=mt[j].begin();
ret=max(ret,(*it1)-(*it2));
}
printf("%d\n",ret);
}
}
return 0;
}