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;
}
此生无悔入OI 来生AK IOI

浙公网安备 33010602011771号