1 条题解
-
1
暴力,二进制枚举。
对于每种指标,将他的绝对值展开,都只有两种情况:
$$|x_i(\mathrm{MW}) - x_i(\mathrm{SW})| = \begin{cases} +x_i(\mathrm{MW}) - x_i(\mathrm{SW}), & x_i(\mathrm{MW}) \ge x_i(\mathrm{SW}), \\[6pt] +x_i(\mathrm{SW}) - x_i(\mathrm{MW}), & x_i(\mathrm{MW}) < x_i(\mathrm{SW}). \end{cases} $$也就是说,对于主武器和副武器的每一个指标,他对答案的贡献要么是,要么是,并且这两个的符号恰恰相反。
那一共有种指标,每种指标有加和减两种情况,是不是恰好可以用二进制的和来表示?一共有种情况,每种情况可以用一个位的二进制数来表示,从遍历到就可以枚举所有的情况,第位为就让主武器减、副武器加。第位为就让主武器加、副武器减,对于每个,分别遍历一遍所有的主副武器,分别找到对答案贡献最大的,所有情况取即可。
二进制枚举的过程也可以通过指数级枚举来实现。
时间复杂度:
ACcode1
#include <iostream> #include <algorithm> #include <vector> #define endl '\n' using namespace std; using LL = long long; struct Wea{ int s; int x[6]; }; void solve(){ int n, m, k; cin >> n >> m >> k; vector<Wea> a(n), b(m); for(int i = 0; i < n; i++){ cin >> a[i].s; for(int j = 0; j < k; j++){ cin >> a[i].x[j]; } } for(int i = 0; i < m; i++){ cin >> b[i].s; for(int j = 0; j < k; j++){ cin >> b[i].x[j]; } } LL res = -1e18; for(int mask = 0; mask < (1 << k); mask++){ LL max1 = -1e18; for(int i = 0; i < n; i++){ LL sum = a[i].s; for(int j = 0; j < k; j++){ if(mask >> j & 1) sum -= a[i].x[j]; else sum += a[i].x[j]; } max1 = max(max1, sum); } LL max2 = -1e18; for(int i = 0; i < m; i++){ LL sum = b[i].s; for(int j = 0; j < k; j++){ if(mask >> j & 1) sum += b[i].x[j]; else sum -= b[i].x[j]; } max2 = max(max2, sum); } res = max(res, max1 + max2); } cout << res << endl; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while(T--){ solve(); } return 0; }
ACcode2
#include <iostream> #include <algorithm> #include <vector> #include <climits> #define endl '\n' using namespace std; using LL = long long; struct Wea{ int s; int x[6]; }; int n, m, k; vector<Wea> a, b; vector<int> bit; LL res; void dfs(int pos){ if(pos == k){ LL max1 = -1e18; for(int i = 0; i < n; i++){ LL sum = a[i].s; for(int j = 0; j < k; j++){ if(bit[j]) sum -= a[i].x[j]; else sum += a[i].x[j]; } max1 = max(max1, sum); } LL max2 = -1e18; for(int i = 0; i < m; i++){ LL sum = b[i].s; for(int j = 0; j < k; j++){ if(bit[j]) sum += b[i].x[j]; else sum -= b[i].x[j]; } max2 = max(max2, sum); } res = max(res, max1 + max2); return; } bit[pos] = 0; dfs(pos + 1); bit[pos] = 1; dfs(pos + 1); } void solve(){ cin >> n >> m >> k; a.resize(n); b.resize(m); for(int i = 0; i < n; i++){ cin >> a[i].s; for(int j = 0; j < k; j++) cin >> a[i].x[j]; } for(int i = 0; i < m; i++){ cin >> b[i].s; for(int j = 0; j < k; j++) cin >> b[i].x[j]; } bit.assign(k, 0); res = -1e18; dfs(0); cout << res << endl; } int main(){ ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int T; cin >> T; while(T--){ solve(); } return 0; }
- 1
信息
- ID
- 2277
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 8
- 已通过
- 2
- 上传者