P1648

看守

题目描述

给出 \(d\) 维空间的 \(n\) 个点,求曼哈顿距离最大的两个点的曼哈顿距离。

两个 \(d\) 维的点 \((x_1,x_2,\ldots,x_d)\)\((y_1,y_2,\ldots,y_d)\) 的曼哈顿距离定义为 \(|x_1-y_1|+|x_2-y_2|+\ldots+|x_d-y_d|\)

输入格式

第一行两个整数 \(n\)\(d\)

接下来 \(n\) 行,每行 \(d\) 个整数描述一个点的坐标。

输出格式

输出最大的曼哈顿距离。

样例 #1

样例输入 #1

4 2
2 1
1 4
4 5
5 3

样例输出 #1

6

提示

数据规模与约定

  • 对于 \(60\%\) 的数据,保证 \(d\le2\)
  • 对于 \(100\%\) 的数据,保证 \(2\le n\le10^6\)\(d\le4\)

玄学题目
首先36PTS暴力O(n^2)枚举
然后我们来看看是怎么扯到状压的:
由曼哈顿距离的公式发现带abs 那么每个维度就有2种情况(正负)
那么我们就枚举这2^d种情况
复杂度为O(2^d*n*d)刚好通过本题
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define min(a,b) ((a)>(b)?(b):(a))
#define max(a,b) ((a)>(b)?(a):(b))
struct did{
	int b[5];
}a[1000005];
int n,d,ans;

int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>d;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=d;j++)
			cin>>a[i].b[j];
	for(int k=0;k<=(1<<d)-1;k++)
	{
		int minn=INT_MAX,maxx=INT_MIN;
		for(int i=1;i<=n;i++)	
		{
			int tot=0;
			for(int j=1;j<=d;j++)
			{
				if((k>>j)&1)tot-=a[i].b[j];
				else tot+=a[i].b[j];
			}
			minn=min(minn,tot);
			maxx=max(maxx,tot);
		}
		ans=max(ans,maxx-minn);
	}	
	cout<<ans<<"\n";
	return 0;
} 
posted @ 2023-01-03 22:26  PKU_IMCOMING  阅读(18)  评论(0)    收藏  举报