[模拟(绝对值)]HDU6435(2018多校训练赛第十场 Problem J) CSGO 题解

题目大意

在玩CSGO的你有 n n 把枪和m个弹匣,每把枪有一个威力 Smi S m i ,每个弹匣也有一个威力 Ssi S s i ,但是由于这个游戏神(che)奇(dan)的设定,所以枪和弹匣可能会出现一些奇妙的效果来增强威力,具体来说,每把枪和每个弹匣都有 k k 个参数性x[1],x[2],..,x[k],而一把枪和一个弹匣组合的战斗值为 Smi+Ssi+ki=1|xm[i]xs[i]| S m i + S s i + ∑ i = 1 k | x m [ i ] − x s [ i ] | ,求你能组合出的最大战斗值。

解题报告

我居然又忘了如何对付绝对值的套路……

首先由于绝对值非负,所以 |xy|=max(xy,yx) | x − y | = m a x ( x − y , y − x )

由于我们在求最大值,所以较小的那个值不仅不合法,而且肯定不是最优。这样的话可以将 |xy| | x − y | 分为两类

x x y x − x y y 。然后将x,y分别加入两个属性内,这样就可以直接找出最大值,而不用n2枚举。

但以上都是 k=1 k = 1 的情况,如果 k>1 k > 1 的话,只需要 2k 2 k 枚举每个参数是正还是负,再求最大值就行了。

示例代码

题目传送门

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
int tst,n,m,k,a[100005][10],b[100005][10];
LL ans;
inline char nc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline void readi(int &x){
    x=0; char ch=nc(),lst='+';
    while ('0'>ch||ch>'9') {lst=ch; ch=nc();}
    while ('0'<=ch&&ch<='9') {x=x*10+ch-'0'; ch=nc();}
    if (lst=='-') x=-x;
}
int main()
{
    freopen("csgo.in","r",stdin);
    freopen("csgo.out","w",stdout);
    readi(tst);
    while (tst--){
        readi(n); readi(m); readi(k); ans=0;
        for (int i=1;i<=n;i++)
            for (int j=0;j<=k;j++) readi(a[i][j]);
        for (int i=1;i<=m;i++)
            for (int j=0;j<=k;j++) readi(b[i][j]);
        for (int s=0;s<(1<<k);s++){
            LL Maxa=-(9e18),Maxb=-(9e18),tem;
            for (int i=1;i<=n;i++){
                tem=a[i][0];
                for (int j=1;j<=k;j++) if (s&(1<<(j-1))) tem+=a[i][j]; else tem-=a[i][j];
                Maxa=max(Maxa,tem);
            }
            for (int i=1;i<=m;i++){
                tem=b[i][0];
                for (int j=1;j<=k;j++) if (s&(1<<(j-1))) tem-=b[i][j]; else tem+=b[i][j];
                Maxb=max(Maxb,tem);
            }
            ans=max(ans,Maxa+Maxb);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值