HDU - 6435 Problem J. CSGO 2018 Multi-University Training Contest 10 (二进制枚举+思维)

题意:有N个主武器(MW)和M个副武器(SW),每个武器都有自己的S值,和K个附加属性xi。要选取一对主副武器搭配,搭配后获得的性能由该公式得出:

求获得最大的性能为多少。

分析:由于|xm - xs| = max (xm - xs, xs -xm) 。所以每种武器如果选择,则其属性xi在最后贡献中只有正负两种状态。那么对于每一种武器,其对最终贡献可能有2^K中组合,

若主武器的一种组合为S,则其选取的副武器的组合即为S的补集。所以对每一种组合S,枚举每个武器在该组合下的贡献并记录最大值。

最后遍历2^K种组合,求S与S反搭配的最大值。

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int INF = 0x3f3f3f3f;
LL MW[1<<5],SW[1<<5];
LL ans = 0;
LL x[10];

int main()
{
    #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
        freopen("out.txt","w",stdout);
    #endif
    int T,N,M,K;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d %d",&N, &M, &K);
        memset(MW,-INF,sizeof(MW));
        memset(SW,-INF,sizeof(SW));
        int up = 1<<K;
        for(int i=1;i<=N;++i){
            LL val; scanf("%lld",&val);
            for(int j = 0;j<K;++j) scanf("%lld",&x[j]);
            for(int s=0;s<up;++s){
                LL tmp = val;
                for(int j=0;j<K;++j){
                    if(s&(1<<j)) tmp += x[j];
                    else tmp -= x[j];
                }
                MW[s] = max(MW[s],tmp);
            }
        }  
        for(int i=1;i<=M;++i){
            LL val; scanf("%lld",&val);
            for(int j = 0;j<K;++j) scanf("%lld",&x[j]);
            for(int s=0;s<up;++s){
                LL tmp = val;
                for(int j=0;j<K;++j){
                    if(s&(1<<j)) tmp += x[j];
                    else tmp -= x[j];
                }
                SW[s] = max(SW[s],tmp);
            }
        }
        LL ans = 0;
        for(int s=0;s<up;++s){
            ans = max(ans,MW[s]+SW[up-1-s]);
        }
        printf("%lld\n",ans);
    }
    return 0;
}

 

 

posted @ 2018-08-23 11:03  xiuwenL  阅读(255)  评论(0编辑  收藏  举报