【贪心】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 }

 

posted @ 2020-10-14 20:00  褪色回音  阅读(64)  评论(0)    收藏  举报