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;
}

 

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