X-man

导航

hdu 4666 Hyperspace

#include<stdio.h>
#include<set>
#include<map>
#include<algorithm>
using namespace std;
int main()
{
    int n,k;
    int i,j,q;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        multiset<int>s[20];
        map<int,int>m[20];//定位,删除点
        for(i=1; i<=n; i++)
        {
            int op;
            scanf("%d",&op);
            if(!op)
            {
                int po[6];
                for(j=0; j<k; j++)
                    scanf("%d",&po[j]);
                for(j=0; j<(1<<(k-1)); j++)
                    //枚举符号状态(可证明只需取一半状态,另外一半为其补)
                {
                    int sum=po[0];
                    for(q=0; q<k-1; q++)
                    {
                        if(j&(1<<q))
                            sum-=po[q+1];
                        else
                            sum+=po[q+1];
                    }//在每种状态下的各点权值
                    s[j].insert(sum);
                    m[j][i]=sum;
                }
            }
            else
            {
                int tmp;
                scanf("%d",&tmp);
                for(j=0; j<(1<<(k-1)); j++)
                {
                    s[j].erase(s[j].find(m[j][tmp]));  //之所以找到再删除是因为直接删会删掉所有相同的
                }
            }
            int Max=0;
            for(j=0; j<(1<<(k-1)); j++)
            {
                multiset<int>::iterator f=s[j].begin();
                multiset<int>::iterator e=s[j].end();
                e--;
                Max=max(Max,*e-*f);
            }
            printf("%d\n",Max);
        }
    }
    return 0;
}

 

原理: |x1-y1|+|x2-y2|+... ...+|xm-ym| 去掉绝对值后x、y分别都有2^m种状态,枚举之。

posted on 2013-08-18 17:14  雨钝风轻  阅读(182)  评论(0编辑  收藏  举报