codeforces 1467C

题目链接:https://codeforces.com/problemset/status?my=on

这种题目一般都可以转化成树上的构造问题

转化为每个数字的正负性
可以构造出两种情况:
1.其中两个背包都是正的,另一个背包都是负的
2.一个背包都是正的,另两个背包的最小值是负的,其他都是正的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 300010;

int n1, n2, n3;
ll a[maxn], b[maxn], c[maxn];
ll s1, s2, s3;
ll m1, m2, m3;

ll ans = 0;

ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }

int main(){
	n1 = read(), n2 = read(), n3 = read();
	for(int i = 1 ; i <= n1 ; ++i) a[i] = read(), s1 += a[i];
	for(int i = 1 ; i <= n2 ; ++i) b[i] = read(), s2 += b[i];
	for(int i = 1 ; i <= n3 ; ++i) c[i] = read(), s3 += c[i];
	
	ans = -1e18;

	ans = max(ans, s1 + s2 - s3); 
	ans = max(ans, s2 + s3 - s1);
	ans = max(ans, s3 + s1 - s2);
	
	m1 = a[1], m2 = b[1], m3 = c[1];
	
	for(int i = 2 ; i <= n1 ; ++i) m1 = min(m1, a[i]);
	for(int i = 2 ; i <= n2 ; ++i) m2 = min(m2, b[i]);
	for(int i = 2 ; i <= n3 ; ++i) m3 = min(m3, c[i]);
	
	ans = max(ans, s1 + s2 + s3 - 2 * m1 - 2 * m2);
	ans = max(ans, s1 + s2 + s3 - 2 * m1 - 2 * m3);
	ans = max(ans, s1 + s2 + s3 - 2 * m2 - 2 * m3);
	
	printf("%lld
", ans);
	
	return 0;
}
原文地址:https://www.cnblogs.com/tuchen/p/14286897.html