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; }
为了更好的明天