CSGO HDU 6435

参考:https://blog.csdn.net/ffgcc/article/details/81951339

题目描述

You are playing CSGO.
There are n Main Weapons and m Secondary Weapons in CSGO. You can only choose one Main Weapon and one Secondary Weapon. For each weapon, it has a composite score S.
The higher the composite score of the weapon is, the better for you.
Also each weapon has K performance evaluations x[1], x[2], …, x[K].(range, firing rate, recoil, weight…)
So you shold consider the cooperation of your weapons, you want two weapons that have big difference in each performance, for example, AWP + CZ75 is a good choose, and so do AK47 + Desert Eagle.
All in all, you will evaluate your weapons by this formula.(MW for Main Weapon and SW for Secondary Weapon)

Now you have to choose your best Main Weapon & Secondary Weapon and output the maximum evaluation.

输入

Multiple query.
On the first line, there is a positive integer T, which describe the number of data. Next there are T groups of data.
for each group, the first line have three positive integers n, m, K.
then, the next n line will describe n Main Weapons, K+1 integers each line S, x[1], x[2], …, x[K]
then, the next m line will describe m Secondary Weapons, K+1 integers each line S, x[1], x[2], …, x[K]
There is a blank line before each groups of data.
T<=100, n<=100000, m<=100000, K<=5, 0<=S<=1e9, |x[i]|<=1e9, sum of (n+m)<=300000

输出

Your output should include T lines, for each line, output the maximum evaluation for the corresponding datum.

样例输入

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

样例输出

543 2000

题意:

给你n件主武器和m件副武器 每件武器都有1个综合评定分数S 和k个其他参数x[i]

你要选择一件主武器和一件副武器  两件武器搭配的值为(MW为主武器 SW为副武器)

分析:

最终的答案的选择中 主副武器的x[i]总是一个加对应一个减 一个减对应一个加

所以只需要枚举出2^k种情况 选最大的就可以了

代码:

#include <bits/stdc++.h>
  
using namespace std;
  
const int maxn = 1e5+5;
const int inf = 0x3f3f3f3f;
typedef long long ll;
ll s1[maxn];  
ll s2[maxn];  
ll v1[maxn][10]; 
ll v2[maxn][10];
ll n,m,k;
int T;
int main()
{
      
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&n,&m,&k);
        for(ll i=0;i<n;i++)
        {
            scanf("%lld",&s1[i]);
            for(ll j=0;j<k;j++)
            {
                scanf("%lld",&v1[i][j]);
            }
        }
  
        for(ll i=0;i<m;i++)
        {
            scanf("%lld",&s2[i]);
            for(ll j=0;j<k;j++)
            {
                scanf("%lld",&v2[i][j]);
            }
        }
  
        ll s = 1<<k;  //(共有2的k次情况  每种都有一个最大值  最后选最大的) 
        ll maxans = -inf;
        ll tmp;   
        for(ll i=0;i<s;i++)   
        {
            ll max1 = -inf;
            ll max2 = -inf;
            for(ll j=0;j<n;j++)
            {
               tmp = s1[j];
               for(ll q=0;q<k;q++)
               {
                   if((1<<q)&i)
                        tmp+=v1[j][q];  //v1 v2加减相反
                   else
                        tmp-=v1[j][q];
               }
               max1 = max(max1,tmp);
            }
  
            for(ll j=0;j<m;j++)
            {
                tmp = s2[j];
                for(ll q=0;q<k;q++)
                {
                    if((1<<q)&i)
                        tmp-=v2[j][q];
                    else
                        tmp+=v2[j][q];
                }
                max2 = max(max2,tmp);
            }
            
            maxans = max(maxans,max1+max2);
        }
        printf("%lld
",maxans);
    }
    return 0;
}

注:菜鸡的我看了一上午这道题   一直不会这种按位枚举的方法  

对于这道题 举个栗子吧

若n = 5  v1[][]的加减情况与i的关系(v2[][]相反)

i:0~ 2^5-1  即可枚举出所有情况

原文地址:https://www.cnblogs.com/hao-tian/p/9524465.html