曼哈顿距离

题目:

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;
}
原文地址:https://www.cnblogs.com/lyxzhz/p/11403847.html