传送门:bzoj5068
题解
先把 c i c_i ci乘进值里,则 a n s = m a x [ ( ∑ i = 1 k − 1 ∣ a x i − a y i ∣ ) − ∣ a x k − a y k ∣ ] ans=max[(\sum_{i=1}^{k-1}|a_{xi}-a_{yi}|)-|a_{xk}-a_{yk}|] ans=max[(∑i=1k−1∣axi−ayi∣)−∣axk−ayk∣]。
注意到 ≤ 5 \leq5 ≤5,只看前 k − 1 k-1 k−1项就是一个拆绝对值的问题,直接 2 k − 1 2^{k-1} 2k−1枚举每个绝对值的符号,由于求的是最大值,而不合法的情况值不会大于合法的值。
那么按第 k k k项属性排序加入即可。
代码
#include<bits/stdc++.h>
#define gc getchar
using namespace std;
const int N=1e5+10,inf=0x7f7f7f7f;
int xs[N],n,K,c[N],ans=-inf;
struct P{
int a[6],k;
bool operator<(const P&ky)const{return k<ky.k;}
}t[N];
char cp;
inline void rd(int &x)
{
cp=getchar();int f=0;x=0;
for(;!isdigit(cp);cp=getchar()) if(cp=='-') f=1;
for(;isdigit(cp);cp=getchar()) x=(x<<3)+(x<<1)+(cp^48);
if(f) x*=-1;
}
inline void sol(int S)
{
int i,j,mn=inf,res;
for(i=1;i<K;++i,S>>=1) xs[i]=(S&1)?1:(-1);
for(i=1;i<=n;++i){
for(res=0,j=1;j<K;++j) res+=xs[j]*t[i].a[j];
res-=t[i].k;if(mn<inf) ans=max(ans,res-mn);
if(res<mn) mn=res;
}
}
int main(){
int i,j,s,S,res;
rd(n);rd(K);S=1<<(K-1);
for(i=1;i<=K;++i) rd(c[i]);
for(i=1;i<=n;++i){
for(j=1;j<K;++j){rd(t[i].a[j]);t[i].a[j]*=c[j];}
rd(t[i].k);t[i].k*=c[K];
}
sort(t+1,t+n+1);
for(s=0;s<S;++s) sol(s);
printf("%d",ans);
return 0;
}