【ICPC-20】hdu 4666 Hyperspace

点击打开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;
}

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值