#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 ",Max); } } return 0; }
原理: |x1-y1|+|x2-y2|+... ...+|xm-ym| 去掉绝对值后x、y分别都有2^m种状态,枚举之。