HDU 6435 Problem J. CSGO 杭电多校第十场

题目描述

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

题意是说选一把主武器MW和一把副武器SW,使得这个式子的值最大

 

如果我们读入数据的时候把副武器的S值改成他的相反数,那么这道题就可以看成从两个六维空间下的点集中各选出一个点,求最远的六维曼哈顿距离。

求最远曼哈顿距离其实很简单,比如二维下的曼哈顿距离|xi-xj|+|yi-yj|,那么对于点i来说,去掉绝对值以后,xi会变成±xi,yi会变成±yi,我们设+为1,-为0,那么用一个数tmp的二进制就可以表示xi、yi的正负情况。在同一个状态下(如tmp==2),2的二进制是10,即+x-y,我们枚举每个点的x-y,从中选出最大值与最小值并相减(设xi-yi最大,xj-yj最小),那么相减的结果就是ans[2]=(xi-yi)-(xj-yj) = (xi-xj) + (yj -yi) <= |xi - xj| + |yi - yj|。我们计算出每个状态下的ans值,然后取最大值即为结果。比如在二维情况下,我们相减得到的结果化简后分别是  (xi-xj) + (yi-yj)、(xj-xi) + (yj-yi) 、(xi-xj) + (yj -yi)、(xj-xi) + (yj-yi),而|xi-xj|+|yi-yj|一定是这四种状态之一,所以其实就枚举出了所有的状态。

因为懒得分成两个集合,我把主武器的S值全部加上了1e10,这样主武器与主武器之间的距离、副武器与副武器之间的距离一定会小于任意一个主武器与副武器之间的距离。

#include <bits/stdc++.h>
typedef long long ll;
const int maxn = 100010;
int dem;  //维数
const ll INF = 0x3f3f3f3f;
struct Point{
   ll x[6];
} p[maxn << 1];
int n,m;
ll minx[100], maxx[100];
ll solve()
{
    int tmp = 1 << dem;
    for(int i = 0; i < tmp; i++)
    {
        minx[i] = INF;
        maxx[i] = -INF;
    }
    for(int i = 0; i < n + m; i++)
    {
        for(int j = 0; j < tmp; j++)
        {
            int t = j;
            ll s = 0;
            for(int k = 0; k < dem; k++)
            {
                if(t & 1) 
                    s += p[i].x[k];
                else 
                    s -= p[i].x[k];
                t >>= 1;
            }
            if(maxx[j] < s)
                maxx[j] = s;
            if(minx[j] > s)
                minx[j] = s;
        }
    }
    ll ans = -INF;
    for(int i = 0; i < tmp; i++)
        if(maxx[i] - minx[i] > ans)
            ans = maxx[i] - minx[i];
    return ans - 10000000000;
}
int main()
{
//    freopen("in.txt", "r", stdin);
    int tt;
    scanf("%d", &tt);
    while(tt--)
    {
        scanf("%d%d%d", &n, &m, &dem);
        dem++;
        for(int i=0; i<n; i++)
        {
            for (int j = 0; j < dem; j++)
                scanf("%lld", &p[i].x[j]);
            p[i].x[0] += 10000000000;
        }
        for(int i=0; i<m; i++)
        {
            for(int j=0; j<dem; j++)
              scanf("%lld", &p[i + n].x[j]);
            p[i + n].x[0] = -p[i + n].x[0];
          }
        printf("%lld\n", solve());
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章