[子集枚举+思维]2018 Multi-University Contest 10 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)
S M W + S S W + ∑ i = 1 k ∣ x M W i − x S W i ∣ S_{MW}+S_{SW}+\sum^{k}_{i=1} \vert x_{MW_i}-x_{SW_i} \vert SMW+SSW+i=1kxMWixSWi
Now you have to choose your best Main Weapon & Secondary Weapon and output the maximum evaluation.

翻译

输入 S M W , S S W S_{MW},S_{SW} SMW,SSW, x M W i x_{MW_i} xMWi, x S W i x_{SW_i} xSWi, k k k.
MW为主件,有 n n n个,SW为附件,有 m m m个。
S M W + S S W + ∑ i = 1 k ∣ x M W i − x S W i ∣ S_{MW}+S_{SW}+\sum^{k}_{i=1} \vert x_{MW_i}-x_{SW_i} \vert SMW+SSW+i=1kxMWixSWi的最大值

题解

算是一道比较简单的题目吧qwq.
题目要求求 S i + S j + ∑ p = 1 k ∣ x i , p − y j , p ∣ S_i+S_j+\sum^{k}_{p=1} \vert x_{i,p}-y_{j,p} \vert Si+Sj+p=1kxi,pyj,p的最大值。
实际上 S i + S j S_i+S_j Si+Sj的最大值十分好求,找两个最大的 S S S即可。
∑ p = 1 k ∣ x i , p − y j , p ∣ \sum^{k}_{p=1} \vert x_{i,p}-y_{j,p} \vert p=1kxi,pyj,p这一部分十分不友好。
因此我们想办法将这个绝对值去掉。
注意题目要求我们求最大的绝对值。
我们应先考虑一个子问题:

∣ a i − b j ∣ \vert a_i-b_j \vert aibj的最大值

注意到 ∣ a − b ∣ = m a x ( a − b , b − a ) \vert a-b \vert=max(a-b,b-a) ab=max(ab,ba)
那么 m a x ( ∣ a i − b j ∣ ) = m a x ( m a x ( a i − b j , b j − a i ) ) = m a x ( a i − b j , b j − a i ) = m a x ( a i , − a i ) + m i n ( b j , − b j ) max(\vert a_i-b_j \vert)=max(max(a_i-b_j,b_j-a_i))=max(a_i-b_j,b_j-a_i)=max(a_i,-a_i)+min(b_j,-b_j) max(aibj)=max(max(aibj,bjai))=max(aibj,bjai)=max(ai,ai)+min(bj,bj)
解释一下这一步… m a x ( a i , − a i ) max(a_i,-a_i) max(ai,ai)一定是非负的, m i n ( b j , − b j ) min(b_j,-b_j) min(bj,bj)一定是非正的。
这一步相当于将 a i a_i ai全部强制为正, b i b_i bi全部强制为负然,后找最大值求和
。(至于为什么我真的讲不清楚啊qwq)
等价于 m a x ( a i , − a i ) − m a x ( b j , − b j ) max(a_i,-a_i)-max(b_j,-b_j) max(ai,ai)max(bj,bj)

如果是求 ∣ a i , 1 − b j , 1 ∣ + ∣ a i , 2 − b j , 2 ∣ \vert a_{i,1}-b_{j,1} \vert+\vert a_{i,2}-b_{j,2} \vert ai,1bj,1+ai,2bj,2.
很明显就是 m a x ( a i , 1 + a i , 2 , − a i , 1 − a i , 2 , − a i , 1 + a i , 2 , a i , 1 − a i , 2 ) − m a x ( b j , 1 + b j , 2 , − b j , 1 − b j , 2 , b j , 1 − b j , 2 , − b j , 1 + b j , 2 ) max(a_{i,1}+a_{i,2},-a_{i,1}-a_{i,2},-a_{i,1}+a_{i,2},a_{i,1}-a_{i,2})-max(b_{j,1}+b_{j,2},-b_{j,1}-b_{j,2},b_{j,1}-b_{j,2},-b_{j,1}+b_{j,2}) max(ai,1+ai,2,ai,1ai,2,ai,1+ai,2,ai,1ai,2)max(bj,1+bj,2,bj,1bj,2,bj,1bj,2,bj,1+bj,2)

那么对于 ∑ p = 1 k ∣ x i , p − y j , p ∣ \sum^{k}_{p=1} \vert x_{i,p}-y_{j,p} \vert p=1kxi,pyj,p就是
m a x ( m a x ( ( ∑ p = 1 k ± x i , p ) ) + m a x ( m a x ( ∑ p = 1 k ± y j , p ) ) max(max((\sum^{k}_{p=1} ±x_{i,p}) )+max(max(\sum^{k}_{p=1} ±y_{j,p})) max(max((p=1k±xi,p))+max(max(p=1k±yj,p))
对与±号,我们可以用子集枚举来完成。
答案 S i + S j + ∑ p = 1 k ∣ x i , p − y j , p ∣ S_i+S_j+\sum^{k}_{p=1} \vert x_{i,p}-y_{j,p} \vert Si+Sj+p=1kxi,pyj,p就是
m a x ( ( m a x ( ( ∑ p = 1 k ± x i , p ) + S i ) ) + m a x ( ( m a x ( ∑ p = 1 k ± y j , p ) − S j ) ) max((max((\sum^{k}_{p=1} ±x_{i,p})+S_i) )+max((max(\sum^{k}_{p=1} ±y_{j,p})-S_j)) max((max((p=1k±xi,p)+Si))+max((max(p=1k±yj,p)Sj))
(抱歉,这道题实在讲的太不清楚了)
复杂度 O ( n ∗ 2 k ) O(n*2^k) O(n2k)
放上官方题解:
10.5-1

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<queue>
#include<cstring>
#include<cmath>
using namespace std;
#define MAXN 100000
#define INF 100000000000
int T,n,m,k;
long long S1[MAXN+5],S2[MAXN+5];
long long a[MAXN+5][6];
long long b[MAXN+5][6];
long long ans;
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        scanf("%d%d%d",&n,&m,&k);
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&S1[i]);
            for(int j=0;j<k;j++)scanf("%lld",&a[i][j]);
        }
        for(int i=0;i<m;i++)
        {
            scanf("%lld",&S2[i]);
            for(int j=0;j<k;j++)scanf("%lld",&b[i][j]);
        }
        for(int S=0;S<(1<<k);S++)
        {
            long long maxx=-INF,minn=INF;
            for(int i=0;i<n;i++)
            {
                long long p1=S1[i];
                for(int j=0;j<k;j++)
                if(S&(1<<j))p1+=a[i][j];
                else p1-=a[i][j];
                //printf("%lld\n",p1);
                maxx=max(maxx,p1);
            }
            for(int i=0;i<m;i++)
            {
                long long p1=-S2[i];
                for(int j=0;j<k;j++)
                if(S&(1<<j))p1+=b[i][j];
                else p1-=b[i][j];
                //printf("%lld\n",p1);
                minn=min(minn,p1);
            }
            ans=max(ans,maxx-minn);
        }
        printf("%lld\n",ans);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值