CF1763C

Update on 2023.8.17:修正了一处小错误。

分析题目可知,答案至少为 \(\sum_{i=1}^{n} a_i\)。接下来考虑怎样使答案更大。

可以对 \(n\) 分成如下几类情况讨论:

  • \(n=2\)

这种情况十分简单,如果选择操作最多一次,否则两次就会变为 \(0\)。用 $ \left| a_1 - a_2 \right | \times 2$ 判断是否能更新答案即可。

  • \(n=3\)

这种情况较为复杂,再细分成几种情况:

  1. \(a_1\) 为最大值。此时对区间 \([2,3]\) 进行两次操作,将其全部变为 \(0\),再对区间 \([1,3]\) 进行一次操作,即可将整个序列都变为 \(a_1\)。用 \(a_1 \times n\) 判断是否能更新答案即可。

  2. \(a_3\) 为最大值。与情况 \(1\) 同理。

  3. \(a_2\) 为最大值。选择 \([1,2]\)\([2,3]\) 区间进行一次操作,再选择 \([1,3]\) 区间进行一次操作,对每次操作后的序列都求和并判断是否能更新答案。

  • \(n>3\)

易证,经过若干次操作后,答案最大能更新为 $ \max {a} \times n$,读者如果感兴趣可以模拟序列 \([1,2,3,2]\) 的变换过程,体会其原理。

上代码,具体实现详见下面。

#include <iostream>
#include <cstdio>
#include <cmath>
#define int long long

using namespace std;

int n,a[1000001],ans,mx;

signed main()
{
	int T;
	cin >> T;
	while( T -- )
	{
		ans = 0;
		mx = 0;
		cin >> n;
		for( int i = 1 ; i <= n ; i ++ )
		{
			cin >> a[i];
			ans += a[i];
			mx = max( mx , a[i] );
		}
		if( n == 2 ) cout << max( ans , abs( a[1] - a[2] ) * 2 ) << endl;
		if( n == 3 ) cout << max( ans , max( max( a[1] * 3 , a[3] * 3 ) , max( max( abs( a[1] - a[2] ) * 2 + a[3] , abs( a[3] - a[2] ) * 2 + a[1] ) , max( abs( a[1] - a[2] ) * 3 , abs( a[3] - a[2] ) * 3 )) ) ) << endl; 
		if( n > 3 ) cout << max( ans , mx * n ) << endl;
	}
	return 0;
}
posted @ 2024-01-20 18:16  liyilang2021  阅读(3)  评论(0编辑  收藏  举报