hdu 4666 Hyperspace

来源:互联网 发布:java正则表达式实例 编辑:程序博客网 时间:2024/06/09 20:57

点击打开hdu 4666

思路:n维空间计算最远的曼哈顿距离
分析:
1 这一题和poj2926很像,但是poj那题是静态的而这边则是动态的,对于静态的话我们知道只要去求出2^n状态下的最大值和最小值,然后求最大的差值即为ans
2 但是对于动态的来说我们需要去维护每一个状态的最大值和最小值,因此我们利用multiset来保存每一个状态下的所有的值,因为multiset是自动排序那么我们就可以很好的求出最大值和最小值
3 注意这边保存点不能够用struct要用数组,因为每次保存在结构体里面的话回去调用构造函数时间开销很大

代码:

#include<set>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N = 5;const int MAXN = 60010;int n , k , pos;int numId[MAXN];int mat[MAXN][N];multiset<int> mst[1<<N];void init(){    pos = 0;    for(int i = 0 ; i < (1<<k) ; i++)        mst[i].clear();    }int getSum(int id , int s){    int sum = 0;    for(int i = 0 ; i < k ; i++){        if(s&(1<<i))             sum += mat[id][i];        else            sum -= mat[id][i];    }    return sum;}void add(){    for(int i = 0 ; i < (1<<k) ; i++){        int sum = getSum(pos , i);        mst[i].insert(sum);    }}void remove(int id){    for(int i = 0 ; i < (1<<k) ; i++){        int sum = getSum(id , i);        multiset<int>::iterator it;        it = mst[i].find(sum);        mst[i].erase(it);    }}int getAns(){    multiset<int>::iterator it;    int tmp;    int ans = 0;    for(int i = 0 ; i < (1<<k) ; i++){        it = mst[i].end();         it--;        tmp = *it;        it = mst[i].begin();         tmp -= *it;        ans = max(ans , tmp);    }    return ans;}int main(){    int mark , x , y;    while(scanf("%d%d" , &n , &k) != EOF){        init();        for(int i = 0 ; i < n ; i++){            scanf("%d" , &mark);            if(mark == 0){                numId[i+1] = pos;                for(int j = 0 ; j < k ; j++)                    scanf("%d" , &mat[pos][j]);                 add();                pos++;            }            else{                scanf("%d" , &x);                remove(numId[x]);             }               printf("%d\n" , getAns());        }    }    return 0;}


原创粉丝点击