AcWing 1247. 后缀表达式

原题链接

考察:贪心

错误思路一:

       排序,加上n+1个较大值,减去m个较小值.

m个减号不一定是全部用来减,可以利用两个减号a-(b-c)转化为a-b+c,如果a-b+c>a+b-c此思路就错误.

正确思路:

        如果要凑最大值,那么需要()max-()min.但是这样的表达式看起来只需要一个+,如果我们把后面的括号去掉就可以获得更多的减号,由此可以发现,如果括号外是-,可以凑成+号和-号.也就是说我们看起来只有n个-号,实际上最多能凑成m+n个减号,最少是min(1,m)个减号.所以这道题不需要考虑将+和-号放哪些位置.

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 using namespace std;
 5 const int N = 200010;
 6 typedef long long LL;
 7 int a[N],cnt;
 8 LL ans,sum;
 9 int main()
10 {
11     int n,m,k = 0;
12     scanf("%d%d",&n,&m);
13     cnt = n+m+1;
14     for(int i=1;i<=cnt;i++) scanf("%d",&a[i]),sum+=(LL)a[i];
15     sort(a+1,a+cnt+1);
16     for(int i=1;i<=cnt;i++)
17     {
18         if(a[i]<0) ans-=(LL)a[i],k++;
19         else ans+=(LL)a[i];
20     }
21     if(m&&k<1) ans = ans-a[1]-a[1];
22     else if(m&&k>m+n) ans = ans+a[cnt]+a[cnt];
23     if(!m) ans = sum;
24     printf("%lld\n",ans);
25     return 0;
26 }

 

posted @ 2021-02-27 02:04  acmloser  阅读(42)  评论(0编辑  收藏  举报