我还是抄解题报告的,感觉想法很妙 http://blog.sina.com.cn/s/blog_5123df350100h3bu.html
/**//* 题目大意:给定N维空间的一些点,求加权曼哈顿距离最近的两个点的距离。 分析: 权值可以乘到点坐标上去,就是说可以把每个点每一维都乘上对应的w[t]。 考虑2维的情况 |x1-x2|+|y1-y2| 最大值只有4种情况: (x1+y1)-(x2+y2) , (-x1+y1)-(-x2+y2), (-x1-y1)-(-x2-y2), (x1-y1)-(x2-y2), 最大值是4种之一,这里面取最大就可以了。 尽一步看到4种形式,每种自身第一个点和第二个点坐标间加正负号的方法是一样的。 推广到N维,我们枚举加符号的方式,一共(1<<M)种,然后对每种方式, 每个点的坐标按枚举的加括号的方式N维运算求出一个值来,取最大和最小值的差, 作为可能结果,最后取所有差值中最大的即可。(注意M很小,只有8)复杂度O(2M*n) */ #include<cstdio> #include<cstring> #define max(a,b) (a)>(b)?(a):(b) #define min(a,b) (a)<(b)?(a):(b)
const int MAXN=50001; const int M=9; const int inf=1000000000;
int cb[MAXN][M],w[M]; int n,m;
int main(){ while(~scanf("%d%d",&n,&m)){
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&cb[i][j]); for(int j=1;j<=m;j++) scanf("%d",&w[j]);
int limit=1<<m,ans=0; for(int k=0;k<limit;k++){ int Max=-inf,Min=inf; for(int i=1;i<=n;i++){ int tmp=0; for(int t=0;t<m;t++){ if(k&(1<<t))tmp+=w[t+1]*cb[i][t+1]; else tmp-=w[t+1]*cb[i][t+1]; } Max=max(tmp,Max); Min=min(tmp,Min); } ans=max(ans,Max-Min); } printf("%d\n",ans); } return 0; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|