看这个老哥补的题,感觉设计的很巧妙传送门
关键点就是对式子中|a1-b1|+|a2-b2|+|a3-b3|所有的符号情况进行枚举一共有2^k种然后在所有武器中去最大值 最后一步对主武器和副武器的情况在二进制中互补中取最大值即可!(好巧妙)
#include #include #include #include #include #include #include #include #include #include #include #include #include #include #define INF 0x3f3f3f3f #define maxn 105000 #define maxnn 6000 #define juzheng 300 #define line cout << "-------------------------" << endl; #define PI acos(-1.0) #define mem(a,b) memset(a,b,sizeof(a)) #define fill_(a,b,n) fill(a,a + n,b) #define esp 1e-9 #define ri(n) scanf("%d",&n) #define ri2(a,b) scanf("%d %d",&a,&b) #define ri3(a,b,c) scanf("%d %d %d",&a,&b,&c) #define rd(n) scanf("%lf",&n) #define rd2(a,b) scanf("%lf %lf",&a,&b) #define rd3(a,b,c) scanf("%lf %lf %lf",&a,&b,&c) #define rl(n) scanf("%lld",&n) #define rl2(a,b) scanf("%lld %lld",&a,&b) #define rl3(a,b,c) scanf("%lld %lld %lld",&a,&b,&c) #define rui(n) scanf("%u",&n) #define rui2(a,b) scanf("%u %u",&a,&b) #define rui3(a,b,c) scanf("%u %u %u",&a,&b,&c) #define rs(str) scanf("%s",str) #define pr(n) cout << n << endl #define debug(str,x) cout << str << ":" << x << endl #define ll long long #define int64 __int64 #define ui unsigned int using namespace std; const ll mod = 1e9 + 7; //Date:2018-8-23 //Author:HarryBlackCat ll n,m,K,a[maxn],b[maxn],arr[maxn],s; void init() { mem(a,-INF); mem(b,-INF); mem(arr,0); } int main() { //cin.sync_with_stdio(false);//降低cin,cout时间 int t; while(~ri(t)) { while(t--) { init(); rl3(n,m,K); for(int i = 0; i < n; i++) { rl(s); for(int j = 0; j < K; j++) rl(arr[j]); for(int j = 0; j < (1 << K); j++) { ll ret = s; for(int k = 0; k < K; k++) { ret += arr[k] * ((1 & (j >> k)) ? 1 : -1); } a[j] = max(ret,a[j]); } } for(int i = 0; i < m; i++) { rl(s); for(int j = 0; j < K; j++) rl(arr[j]); for(int j = 0; j < (1 << K); j++) { ll ret = s; for(int k = 0; k < K; k++) { ret += arr[k] * ((1 & (j >> k)) ? 1 : -1); } b[j] = max(ret,b[j]); } } ll ans = 0; for(int i = 0,j = (1 << K) - 1; i < (1 << K); i++,j--) ans = max(ans,a[i] + b[j]); pr(ans); } } return 0; }