HDU 6435 Problem J. CSGO(水~)

Description

武器分主武器和副武器,每种武器有固定分数SSk个属性x1,...,xkx1,...,xk,每次只能选一个主武器和一个副武器,两者搭配的分数为两者固定分数之和加上每项属性差的绝对值,问最高分数搭配

Input

第一行一整数TT表示用例组数,每组用例首先输入三整数n,m,k表示主武器数量、副武器数量以及每种武器的属性数,之后n+mn+m行输入nn种主武器和m种副武器的固定分数和kk种属性

(1T100,1n,m105,1k5,0S109,|xi|109)

Output

输出最高分数

Sample Input

2
2 2 1
0 233
0 666
0 123
0 456
2 2 1
100 0 1000 100 1000 100
100 0

Sample Output

543
2000

Solution

由于一件主武器的kk种属性的在得分表示中的符号至多只有2k32种情况,而副武器的符号与这件武器的符号相反,故直接枚举这2k2k种主武器符号,得到每种主武器和副武器在该种符号安排下的得分和,维护最大值即为答案

Code

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn 100005
int T,n,m,k;
struct node
{
    int x[6],S;
    ll w;
}a[maxn],b[maxn];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i].S);
            for(int j=0;j<k;j++)scanf("%d",&a[i].x[j]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%d",&b[i].S);
            for(int j=0;j<k;j++)scanf("%d",&b[i].x[j]);
        }
        ll ans=-1e18;
        int K=1<<k;
        for(int S=0;S<K;S++)
        {
            int s1[6],s2[6];
            for(int i=0;i<k;i++)
                if((S>>i)&1)s1[i]=1,s2[i]=-1;
                else s1[i]=-1,s2[i]=1;
            ll ma=-1e18,mb=-1e18;
            for(int i=0;i<n;i++)
            {
                a[i].w=a[i].S;
                for(int j=0;j<k;j++)a[i].w+=s1[j]*a[i].x[j];
                ma=max(ma,a[i].w);
            }
            for(int i=0;i<m;i++)
            {
                b[i].w=b[i].S;
                for(int j=0;j<k;j++)b[i].w+=s2[j]*b[i].x[j];
                mb=max(mb,b[i].w);
            }
            ans=max(ans,ma+mb);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值