【贪心】AcWing 1247. 后缀表达式
题目:https://www.acwing.com/problem/content/1249/
第一次看,理解错了后缀表达式的意思。
这道题目中的后缀表达式是逆波兰表达式,对应一颗二叉树的后序遍历(同理前、中缀表达式对应先序、中序遍历序列)。
比如:b a c - d - - 就可以转换为 b - (a - c - d) = b - a + c + d
所以可以看出来,这道题目中符号的数量是可以有变化的。
如果全部都是加号,就可以直接算。
如果有减号,那么加号与减号的个数是可以改变的,但是至少会有一个减号,那么这个减号显然就要给数列中的最小值,其余的数随意分配符号就好了,即:ans += abs(x),使其为正数(贪心策略)
(代码是y总的代码)
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 6 using namespace std; 7 8 typedef long long LL; 9 10 const int N = 200010; 11 12 int n, m; 13 int a[N]; 14 15 int main() 16 { 17 scanf("%d%d", &n, &m); 18 int k = n + m + 1; 19 for (int i = 0; i < k; i ++ ) scanf("%d", &a[i]); 20 21 LL res = 0; 22 if (!m) 23 { 24 for (int i = 0; i < k; i ++ ) res += a[i]; 25 } 26 else 27 { 28 sort(a, a + k); // 也可以不排序,找出最大值和最小值即可 29 30 res = a[k - 1] - a[0]; 31 for (int i = 1; i < k - 1; i ++ ) res += abs(a[i]); 32 } 33 34 printf("%lld\n", res); 35 36 return 0; 37 }

浙公网安备 33010602011771号