CWT大逃亡 escape题解

题目描述

     因为害怕JY的瘴气,CWT开始的大逃亡,可是JY在穷追不舍。
     慌不择路下,CWT跳进了一个K维空间,JY自然也追了进来。
     这个K维空间里有N座城市,CWT和JY分别会选择一座城市休息,CWT当然希望自己所在的城市能离JY所在的城市最远,以减少瘴气对他的影响。
     因为CWT是非常乐观的,他认为他和JY会分别在距离最远的那两座城市,所以他只想知道距离最远的两座城市的距离是多少。(这里的距离指曼哈顿距离,P1(x1,y1)与坐标P2(x2, y2)的曼哈顿距离为:|x1 - x2| + |y1 - y2|. )

输入

第一行包括两个整数n和k,表示有n个城市,是k维空间。
第二到第n+1行,每行k个整数,表示该城市的坐标。

输出

输出一行一个数表示最远的距离。

样例输入

4 4
0 0 0 0
1 2 3 4
4 3 2 1
-2 -1 0 1

样例输出

12

提示

【样例解释】

    从2号或者3号城市走到4号城市,距离均为12。

【数据范围】

    20%的数据满足n<=1000。 

    另外20%的数据满足k=1。 

    另外30%的数据满足k=2。

    100%的数据满足,n<=50000,k<=7.

    所有出现的数的绝对值<=10^8。 

    输入数据不超过5M。

想法

  • 该题的模型就是最远曼哈顿距离
  • 先从k=2的情况分析
  • 观察曼哈顿距离的式子 |x1-x2|+|y1-y2|
  • 将绝对值拆去分类讨论
  • ①x1-x2+y1-y2==>(x1+y1)-(x2+y2)
  • ②x1-x2+y2-y1==>(x1-y1)-(x2-y2)
  • ③x2-x1+y1-y2==>(-x1+y1)-(-x2+y2)
  • ④x2-x1+y2-y1==>(-x1-y1)-(-x2-y2)
  • 发现x1 y1的系数与x2 y2的系数相同 推广到k维

算法

  • 将每一维坐标的系数压成一个二进制位
  • 用Ma[S]表示S状态下的最大值 Mi[S]表示S状态下的最小值
  • ans必然从Ma[S]-Mi[S]中选出

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define MAXN 50005
#define INF 1<<30
using namespace std;
int n,k;
typedef long long ll;
ll Ma[1<<8],Mi[1<<8],ans;
struct Tpoint
{
    int a[10];
}p[MAXN];
inline void solve()
{
    int ind=1<for (int i=0;ifor (int i=1;i<=n;i++)
    {
        for (int j=0;j0;
            for (int l=1;l<=k;l++)
            {
                if(in&1)s+=p[i].a[l];
                else s-=p[i].a[l];
                in>>=1;
            }
            if(Ma[j]if(Mi[j]>s)Mi[j]=s;
        }
    }
    for (int i=0;icout<int main()
{
    //freopen("escape.in","r",stdin);
    //freopen("escape.out","w",stdout);
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++)
        for (int j=1;j<=k;j++)
            scanf("%d",&p[i].a[j]);
    solve();
    return 0;
}

你可能感兴趣的:(题解,状态压缩)