版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/monochrome00/article/details/81950448
题目链接<http://acm.hdu.edu.cn/showproblem.php?pid=6435>
题意:
有n个主武器,m个副武器。每个武器都有一个攻击力,和k个属性。要选择一个主武器和一个副武器组合,使得最后的攻击力最大。攻击力计算方法:属性之差的绝对值之和加上两个武器的攻击力。
题解:
利用最远曼哈顿距离的套路计算。
一个维度曼哈顿距离是|x1- x2|。将绝对值去掉就有两种状态:(+x1)+ (-x2)和(-x1)+(+x2)。
一维的状态数是,五维就是=32。每把枪预处理出每个状态,记录每个状态下的最大值。
最后将每个主武器的状态与对应的副武器的状态,取个最大的价值和就是答案。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[40],b[40],x[6];
int main()
{
ll t,n,m,k,val;
scanf("%lld",&t);
while(t--){
scanf("%lld%lld%lld",&n,&m,&k);
memset(a,128,sizeof(a));
memset(b,128,sizeof(b));
for(ll i=1;i<=n;i++){
scanf("%lld",&val);
for(ll j=0;j<k;j++)
scanf("%lld",&x[j]);
for(ll s=0;s<(1<<k);s++){
ll tmp=val;
for(ll j=0;j<k;j++){
if((1<<j)&s) tmp+=x[j];
else tmp-=x[j];
}
a[s]=max(a[s],tmp);
}
}
for(ll i=1;i<=m;i++){
scanf("%lld",&val);
for(ll j=0;j<k;j++)
scanf("%lld",&x[j]);
for(ll s=0;s<(1<<k);s++){
ll tmp=val;
for(ll j=0;j<k;j++){
if((1<<j)&s) tmp+=x[j];
else tmp-=x[j];
}
b[s]=max(b[s],tmp);
}
}
ll ans=0;
for(ll i=0;i<(1<<k);i++){
ll j=((1<<k)-1-i);
ans=max(ans,a[i]+b[j]);
}
printf("%lld\n",ans);
}
}