Problem J. CSGO
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 294 Accepted Submission(s): 145
Problem Description
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)
Now you have to choose your best Main Weapon & Secondary Weapon and output the maximum evaluation.
Input
Multiple query.
On the first line, there is a positive integer T, which describe the number of data. Next there are T groups of data.
for each group, the first line have three positive integers n, m, K.
then, the next n line will describe n Main Weapons, K+1 integers each line S, x[1], x[2], …, x[K]
then, the next m line will describe m Secondary Weapons, K+1 integers each line S, x[1], x[2], …, x[K]
There is a blank line before each groups of data.
T<=100, n<=100000, m<=100000, K<=5, 0<=S<=1e9, |x[i]|<=1e9, sum of (n+m)<=300000
Output
Your output should include T lines, for each line, output the maximum evaluation for the corresponding datum.
Sample Input
2 2 2 1 0 233 0 666 0 123 0 456 2 2 1 100 0 1000 100 1000 100 100 0
Sample Output
543 2000
Source
2018 Multi-University Training Contest 10
题意:这题最暴力的写法就是枚举任意两个,复杂度O(nm),超时,但是这道题的k很小,可以从k入手
|x1-y1| = max(x1 - y1,y1 - x1),x1的系数不是1就是-1,当k=5共2^5次种情况,所以我们枚举主武器每一种情况对应的最大值,副武器每一种情况对应的最大值,最后取最大值
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
const int INF = 0x3f3f3f3f;
ll A[50],B[50];
ll k[6];
int main(void)
{
int T,n,m,s;
ll val,temp,ans;
scanf("%d",&T);
while(T--) {
memset(A,-INF,sizeof(A));
memset(B,-INF,sizeof(B));
scanf("%d %d %d",&n,&m,&s);
for(int i = 1; i <= n; i++) {
scanf("%lld",&val);
for(int j = 0; j < s; j++) {
scanf("%lld",&k[j]);
}
//枚举每一种情况对应的最大值
for(int j = 0; j < (1 << s); j++) {
temp = val;
//二进制一位一位的枚举
for(int q = 0; q < s; q++) {
//0的话为-1,1的话为1
temp += k[q] * ((((j >> q) & 1) << 1) - 1);
}
//printf("%lld--\n",temp);
A[j] = max(A[j],temp);
}
}
for(int i = 1; i <= m; i++) {
scanf("%lld",&val);
for(int j = 0; j < s; j++) {
scanf("%lld",&k[j]);
}
for(int j = 0; j < (1 << s); j++) {
temp = val;
for(int q = 0; q < s; q++) {
temp += k[q] * ((((j >> q) & 1) << 1) - 1);
}
//printf("%lld--\n",temp);
B[j] = max(B[j],temp);
}
}
ans = 0;
for(int i = 0; i < (1 << s); i++) {
//printf("%d %d\n",i , (1 << s) - 1 - i);
//printf("%lld %lld\n",A[i] , B[(1 << s) - 1 - i]);
//取最大值,主武器为-1 1 1 1 -1,那副武器为1,-1,-1,-1,1
ans = max(ans,A[i] + B[(1 << s) - 1 - i]);
}
printf("%lld\n",ans);
}
return 0;
}
/*
2
2 2 1
0 233
0 666
0 123
0 456
2 2 1
100 0
1000 100
1000 100
100 0
*/