题目:
Description
给出N个D维空间的点。求出曼哈顿距离最大的两个点的曼哈顿距离。两个点(x1,x2,…,xd)、(X1,X2,…XD)的曼哈顿距离为|x1-X1|+|x2-X2|+…+|xd-XD|。
Input
第一行两个整数N,D(1<N<1000000,1≤D≤5)。接下来的N行,每行描述一个坐标点。
Output
曼哈顿距离最大的两个点的曼哈顿距离。
DFS+位运算
公式推导:
- |x1-X1|=max{x1-X1,-x1+X1}
- |x1-X1|+|x2-X2|=max{x1-X1+x2-X2,x1-X1-x2+X2,-x1+X1+x2-X2,-x1+X1-x2+X2}
- find:每一个x如果考虑正负号,D=2时有4种表达式,所以有2^D个表达式.观察max中的元素,每个式子中的xi和Xi的符号相反。
思路:
- 将正号看作1,负号看作0,就能用位数为D的二进制数表示状态
代码:
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> using namespace std; long long INF=100000007; int a[1000005][6],n,d,ans; int main() { scanf("%d%d",&n,&d); for (int i=1; i<=n; i++) for (int j=1; j<=d; j++) scanf("%d",&a[i][j]); int sum,Max,Min; for (int k=0; k<(1<<d); k++)//枚举2^D种状态 { Max=-INF; Min=INF;//计算每种状态下的最大值和最小值 for (int i=1; i<=n; i++) { sum=0; for (int j=1; j<=d; j++) if (k&(1<<(j-1))) sum+=a[i][j];//符号为正,sum加上当前值 else sum-=a[i][j];//符号为负 Max=max(Max,sum); Min=min(Min,sum); } ans=max(ans,Max-Min); } printf("%d\n",ans); return 0; }