http://oj.ecustacm.cn/problem.php?id=1467
蓝桥赛前练练手~~
后缀表达式可以模拟任意加括号的结果
所以相当于给出n个加号,m个减号,n+m+1个数,用这些任意组成一个式子,使结果最大
用大写字母表示正数,小写字母表示负数
最优的情况是n+m+1个数中,有n+1个正数,有m个非正数
即构成A+B+C+D-a-b-c形式
结果就是绝对值之和
在此基础上
如果减号多了,说明需要给正数前分配减号
1、如果有非正数,那么可以构成A-(a-B)=A-a+B,依然是绝对值之和
2、如果全是正数,那么可以构成A-(B-C)=A-B+C,显然需要B最小,结果就是绝对值之和-2*最小正数
如果加号多了,说明需要给负数前分配加号
1、如果没有减号,那么只能是A+a+b,结果就是所有数的和
2、如果有减号而且有正数,那么可以构成A-(a+b)=A-a-b,结果是绝对值之和
如果有减号而且没有正数,a-(b+c)=a-b-c,需要a最大,结果就是绝对值之和+2*最大非正数
#include<cstdio> #include<algorithm> using namespace std; #define N 100001 int main() { int n,m; scanf("%d%d",&n,&m); int tot=n+m+1,x,s1=0,s2=0; long long sa=0,sb=0; int mi=1e9; for(int i=1;i<=tot;++i) { scanf("%d",&x); if(x>0) s1++,sa+=x; else s2++,sb-=x; mi=min(mi,abs(x)); } if(m==s2) printf("%lld",sa+sb); else if(m>s2) { if(s2) printf("%lld",sa+sb); else printf("%lld",sa+sb-2*mi); } else { if(m) { if(s1) printf("%lld",sa+sb); else printf("%lld",sb-2*mi); } else printf("%lld",sa-sb); } }