案例:后缀表达式

文章介绍了如何将包含加号和减号的中缀表达式转换为后缀表达式,并指出在保持一个操作数不变号、一个取反、其余取绝对值的情况下,如何通过排序最大化表达式的值。给出的C++代码示例展示了这个过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

中缀表达式转换为后缀表达式的方法
以(2+3)*5为例:
①将所有运算按照优先级加上小括号,得到:((2+3)*5)
②将运算符移到对应小括号后,得到:( ( 2 3 ) + 5 ) *
③去掉小括号,得到:2 3 + 5 * 

分析:

如果M=0,即没有减号,易知,N+1个数相加的结果是确定的,因此, 最大值就是输入的N+1个数的和
以下讨论都是针对M>0的情形,即至少有一个减号
输入的是后缀表达式, 没有括号, 但等价的中缀表达式, 可能有括号
例如,后缀表达式2 3 5 + -,等价的中缀表达式是:2-(3+5)

本题只有+和-,而-号在括号前可以把括号内的所有加号或减号进行取反,例如:
a-(b +c+d+e)=a-b-c-d-e,将3个加号变为负号
a-(b-c-d-e)=a-b+c+d+e,将3个减号变为正号
a-(b +c)-(d+e)=a-b-c-d-e,括号前的-号都把括号内的符号取反
a-(b-c)-(d-e)=a-b+c-d+e,括号前的-号都把括号内的符号取反 

因此, 虽然输入N+M+1个数,原本有N个+号,M个-号,但可以转变成任意X个加号、Y个减号,其中X,Y满足X+Y==N+M,X≥0,Y≥1,即至少有一个减号

题目没有要求输入的N+M+1个数必须严格按输入顺序出现在后缀表达式中,这就意味着为了使得表达式的取值最大, 可以将这些数任意组合,比如几个负数先在括号内加起来,括号前面再放一个减号

但是,转换以后的表达式最前面的操作数无法改变符号,且至少有一个减号。所以最后的结果为:N+M+1个数中,一个数不改变符号、一个数加上负号取反、其他数可取绝对值,容易看出不改变符号的数应该选最大值,取反的数应该选最小值,这时表达式的值最大。对输入的N+M+1个数排序即可实现
用向量存储输入的N+M+1个数。 对向量进行排序和求和都是非常方便的 

代码如下:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e5 + 10;
int main(){
	int i, N, M;
	cin >> N >> M;
	vector<int> v(N+M+1);
	for(i=0;i<N+M+1;i++) cin >> v[i];
	if(M==0){
		cout << accumulate(v.begin(), v.end(), 0LL) << endl;
		return 0;
	}
	sort(v.begin(), v.end());  //从小到大排序 
	LL ans = v[N+M+1-1] - v[0];
	for(i=1;i<N+M;i++) ans += abs(v[i]); 
	cout << ans << endl; 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值