HDU-6435 Problem J. CSGO (最大曼哈顿距离)

Problem J. CSGO

题目链接: Problem J. CSGO

题意

有n个主武器,m个副武器,(n < 1e5,m < 1e5)每个武器有个主属性S和一个 K(K < 5)个副属性,现在要求以下值最大 S1+S2+Ki=1|XniXmi| S 1 + S 2 + ∑ i = 1 K | X n i − X m i |


思路

这里求最大曼哈顿距离,非常有意思。因为曼哈顿距离中的定义是 |x1x2|+|y1y2| | x 1 − x 2 | + | y 1 − y 2 | 每个 x1,x2 的状态显然是相反的,也就是 +–+ 对应的是 -++-,现在我们只需枚举 1 << k 种情况,在找到与之对应的情况,进行判断即可,这样的复杂度是 nk3 n ∗ k 3 的所以一定没问题。

补充:在初始化时,一定要将点赋值无穷小。


代码

#include 
using namespace std;
#define rep(i,j,k) for(ll i = (ll)j;i <= (ll)k;i ++)
#define per(i,j,k) for(ll i = (ll)j;i >= (ll)k;i --)
#define debug(x) cerr<<#x<<" = "<<(x)<
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back

typedef double db;
typedef long long ll;
const ll MAXN = (ll)1e5+7;
const ll INF = (ll)0x3f3f3f3f;

ll w[1<<5];
ll c[6];

void init() {
    mmm(w,0);
}

int main()
{
    ll T;
    scanf("%lld",&T);
    while (T --) {
        ll n,m,K;
        scanf("%lld %lld %lld",&n,&m,&K);
        init();
        rep(i,1,n) {
            ll s;
            scanf("%lld",&s);
            rep(i,1,K) scanf("%lld",&c[i]);
            rep(j,0,(1<1){
                ll tmp = s;
                rep(h,1,K) {
                    if (j&1<<(h-1)) tmp += c[h];
                    else            tmp -= c[h];
                }
                w[j] = max(tmp,w[j]);
            }
        }
        ll ans = 0;
        rep(i,1,m) {
            ll s;
            scanf("%lld",&s);
            rep(i,1,K) scanf("%lld",&c[i]);
            rep(j,0,(1<1){
                ll tmp = s;
                rep(h,1,K) {
                    if (j&1<<(h-1)) tmp -= c[h];
                    else            tmp += c[h];
                }
                ans = max(ans,tmp+w[j]);
            }
        }
        printf("%lld\n",ans);
    }
}

你可能感兴趣的:(算法集训)