• Luogu P1648 看守


    Luogu P1648 看守

    题意简述

    有n个d维的点,输出这些点两两之间曼哈顿距离中的最大值

    数据范围

    n<=1e6,d<=4

    思路

    暴力?时间复杂度O((n^2d)

    考虑这样的一个式子

    [x-y<=|x-y| ]

    因为我们是求最大值,那么,我们把绝对值去掉似乎也无妨

    对于每一个点,记录(2^d)个数,每一个二进制数就表示当这一维取正/负时的取值

    例如

    如果这个点的坐标为(1,2,3)那么000就表示 -1-2-3=-6 ,001就表示 -1-2+3=0

    我们不难发现,当两个二进制数每一位恰好相反时,把这两个值加起来就表示一个“曼哈顿距离”(去掉了绝对值)
    因为d非常小,所以我们可以对于每一个点枚举(2^d)个状态,然后对于每一类状态记录一个最大值
    统计答案是把相反的两个加起来即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int sz=1e6+1;
    int n,d;
    int cnt,ans;
    int a[sz][5];
    int f[16][sz];
    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]);
        cnt=1<<d;
        for(int i=0;i<cnt;i++)
        for(int j=1;j<=n;j++)
        for(int k=1;k<=d;k++){
            if(i&1<<(k-1)) f[i][j]+=a[j][k];
            else f[i][j]-=a[j][k];
        }
        for(int i=1;i<cnt;i++){
            int l=INT_MAX,r=INT_MIN;
            for(int j=1;j<=n;j++){
                l=min(l,f[i][j]);
                r=max(r,f[i][j]);
            }
            ans=max(ans,r-l);
        }
        printf("%d",ans);
    }
    
    以仁心说,以学心听,以公心辩
  • 相关阅读:
    Hibernate检索策略与检索方式
    获取分组后的TOP 1和TOP N记录
    Oracle 高级排序函数 和 高级分组函数
    Java中的字符串常量池
    代码的完整性:打印1到最大的n位数
    代码的完整性:数值的整数次方
    递归和循环:矩形覆盖
    位运算:二进制中1的个数
    递归和循环:变态跳台阶
    递归和循环:跳台阶
  • 原文地址:https://www.cnblogs.com/river-flows-in-you/p/10561688.html
Copyright © 2020-2023  润新知