Slime CodeForces - 1038D
题意
一排数字,对其中任意一组相邻的数字α,β,可以用α - β(可以为负)在该位置替换两个数
重复上述操作直到只剩下一个数res
给定数字序列,问res理论最大值
大概两种思路
贪心
1)数学归纳法
A.存在正数 和 负数(0可以作为正数和负数)
对于下一次操作数,如果当前操作数a , b > 0 , c < 0:
a < 0,b - a 可以得到新的正数为两者绝对值和
a > 0,c - a 可以得到新的负数数为两者绝对值和相反数 ,
b - (c - a)可以得到新的正数为三者绝对值和
重复上述步骤,对于每个数字进行操作,可以得到最终结果为所有数绝对值总和
B.只有正数 或者 只有负数
选取两个数作差,回到第一种情况,对于选定的两个数X , Y最终得到
所有数绝对值总和 - |X| - |Y| + |X - Y|
可以搜索得到最优解
C.只有一个数直接输出。
枚举
2)
A.给的数组中既有正数也有负数,那么就总能让负数吞正数,
得到一个绝对值更大的负数,并且吞并后的绝对值是它们的绝对值的和
直到剩下一个正数时,让那个正数把所有的负数吞掉,最后的值,就是所有数的绝对值的和
B.如果只有正数(负数),那么就从这些数中选出一对相邻的数,进行操作,
就能得到一个负数(正数)。就有正有负,进入了第一种情形。
C.特判只有一个数的情形,直接输出那个数。
代码
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<bitset> 6 #include<cassert> 7 #include<cctype> 8 #include<cmath> 9 #include<cstdlib> 10 #include<ctime> 11 #include<deque> 12 #include<iomanip> 13 #include<list> 14 #include<map> 15 #include<queue> 16 #include<set> 17 #include<stack> 18 #include<vector> 19 #include <vector> 20 #include <iterator> 21 #include <utility> 22 #include <sstream> 23 #include <limits> 24 #include <numeric> 25 #include <functional> 26 using namespace std; 27 #define gc getchar() 28 #define mem(a) memset(a,0,sizeof(a)) 29 //#define sort(a,n,int) sort(a,a+n,less<int>()) 30 31 #define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); 32 33 typedef long long ll; 34 typedef unsigned long long ull; 35 typedef long double ld; 36 typedef pair<int,int> pii; 37 typedef char ch; 38 typedef double db; 39 40 const double PI=acos(-1.0); 41 const double eps=1e-6; 42 const ll mod=1e9+7; 43 const int inf=0x3f3f3f3f; 44 const int maxn=1e5+10; 45 const int maxm=100+10; 46 47 48 bool compare(int a, int b) 49 { 50 return a < b;//升序 51 } 52 53 int num[500000] = {0}; 54 int main() 55 { 56 int n = 0; 57 cin >> n; 58 if(n == 1){ 59 cin >> num[0]; 60 cout<< num[0]; 61 return 0; 62 } 63 ll sum = 0; 64 bool flag_n = 0 , flag_p = 0; 65 for(int i = 0;i<n;i++) 66 { 67 cin >> num[i]; 68 sum += abs(num[i]); 69 if(num[i] < 0) flag_n = 1; 70 else flag_p = 1; 71 } 72 73 ll ans = 0; 74 if(flag_n && flag_p) 75 { 76 ans = sum; 77 } 78 else 79 { 80 for(int i = 1;i<n;i++) 81 { 82 ans = max(ans , sum - abs(num[i]) - abs(num[i-1]) + abs(num[i]-num[i-1])); 83 } 84 } 85 cout << ans; 86 return 0; 87 }