后缀&前缀&中缀表达式

后缀&前缀&中缀表达式

1.算法分析

对于任意一个前缀、中缀、后缀表达式,都可以对应到一颗树,该树的叶子节点为数字,根节点为符号。如下图所示:

Screenshot_20201012_225126.jpg

而前缀、中缀、后缀表达式分别是对该树进行前序、中序、后序遍历得到的表达式。

该树前缀表达式、中缀表达式、后缀表达式的答案一样,因此,如果希望得到前缀和后缀表达式的值,直接转化为求中缀表达式的值,等于树的: val(左子树) op val(右子树), 其中的op表示运算符号。

定义整棵树的权值为该树对应的中缀表达式的值。而由于不同根节点允许赋的符号不同,得到的整棵树的权值也不同,这就有了求最值的问题。

设加号有n个,减号有m个,那么一旦m>0,便可以构造出减号1 ~ n+m,加号1 ~ n+m,即最少构造出一个加号、一个减号,其余n+m-2个符号任意。如下图所示:

Screenshot_20201012_231307.jpg

2.典型例题

第十届蓝桥杯 c/c++ 省赛b组 I: 后缀表达式

题意: 给定 N 个加号、M 个减号以及 N + M + 1 个整数 A1, A2, · · · , AN+M+1,小 明想知道在所有由这 N 个加号、M 个减号以及 N + M + 1 个整数凑出的合法的 后缀表达式中,结果最大的是哪一个? 请你输出这个最大的结果。例如使用1 2 3 + -,则 “2 3 + 1 -” 这个后缀表达式结果是 4,是最大的。 0 ≤ N , M ≤ 100000 , − 1 0 9 ≤ A i ≤ 1 0 9 0 ≤ N, M ≤ 100000,−10^9 ≤ Ai ≤ 10^9 0N,M100000109Ai109

题解: 对于任意一个后缀表达式都可以对应到一颗树,该树的叶子节点是所有的数字,根节点是符号。对于这样一棵树只要存在“-”号节点,那么就能够构造出负数1 ~ n+m个,正数1 ~ n+m个,即最少一个正数、一个负数,其他数字的符号任意。因此只需要将原数列排序,最大的取正好,最小的取符号,中间的都取绝对值即可。

代码:

#include <bits/stdc++.h>

using namespace std;

int const N = 2e5 + 10;
typedef long long LL;

int n, T, m, a[N];

int main() {
    cin >> n >> m;
    int k = n + m + 1;
    for (int i = 1; i <= k; ++i) scanf("%d", a + i);
    LL res=  0;
    if (!m) {
        for (int i = 1; i <= k; ++i)
            res += a[i];
    }
    else {
        sort(a + 1, a+ k + 1);
        res = a[n+1+m]-a[1];
        for (int i = 2; i <= n + m; ++i) res += abs(a[i]);
    }
    cout << res << endl;
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值