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 }