3つのバッグCodeForces-1467C

題名:

3つの石の山の場合、1つの石aと1つのbの2つの石の山を取ることができます。次に、b = baになるようにaを削除し、bの山に入れます。小石が1つだけ残るまでこれを行い、小石が最も価値があることを見つけます。

回答:

構築の質問
は、両方の状況を構築できます。

  1. 2つの杭は正で、1つの杭は負です
  2. 1つのバックパックが正で、他の2つのバックパックの最小値が負で、他のバックパックが正です。
    なぜこのように構成されているのですか?
    参照問題解決
    数の場合、奇数の演算が実行されると、それは負の寄与であり、偶数の演算は正の寄与です。
    最後の数値が配列aにあるとすると、n-1があります。に残っている数字は、最後に他の配列と組み合わせることができます。最後の数字と組み合わせると、すべてプラスの貢献になります。同じことがbとcの配列にも当てはまります。これは、bとcの1つの数値のみの負の寄与に相当し、他は正です。bをとると、cの最小値が負の寄与である
    bを直接選択します。 cの配列の1つは正の配列で、もう1つは負の配列です

コード:

#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\n", ans);
	
	return 0;
}

おすすめ

転載: blog.csdn.net/qq_35975367/article/details/114096741