自己想的,贪心的去做,给数组排个序,大的在前面,小的在后面,先把大的相加,把加号用完为止,再去减小的,把减号用完为止:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
signed main()
{
cin.tie(nullptr)->sync_with_stdio(false);
cin>>n>>m;
int t=n+m+1;
vector<int>a(t);
for(int i=0;i<t;i++)cin>>a[i];
sort(a.begin(),a.end(),greater<int>());
int sum=a[0];
int i=1;
while(n--)
{
sum+=a[i];
i++;
}
int j=i;
while(m--)
{
sum-=a[j];
j++;
}
cout<<sum;
return 0;
}
只过了30%,wa错误:
优化
例如 - - + 1 2 3 4,按照上面的思路是这样求的:->4+3-1-2=4。
但是实际上这样求出来并不是最大值。我可以这样求:-> 4+3-(1-2)
这样开出来就是:->4+3-1+2=8
其二,数组中存在元素是负数的可能。例如
而存在负数又有两种情况:
1.负数个数比 负号个数少
2.负数个数 和 负号个数一样
但是对于两种情况,我们都可以把它变为的形式
例如:
(1) - - + 1 -2 3 -4 -> (3 - -4)+( 1 - -2) 可全化为正求和
(2) - - + 1 -2 3 4 -> 4 + 3 - (-2 - 1) 可全化为正求和
因此无论有多少个操作符,操作数是否有负数,我们都可以看一下是否有负号,如果没有负号,那么只需要全部相加即可。
如果有负号,那么我们就可以转化为 a-(b-c-d-……)的形式。
其中最多只会减去一个数,其他的都会转化求和的形式。
为了使整体值最大,我们要使这个减去的数最小,因此,我们可以对数组排个序,然后减去第一个数即可。
code
因为a[i]最大1e9,所以记得开long long,不然只能过70%
数值的个数是操作符的个数和+1,操作符个数最大1e5,所以数字数组要开2e5,不然只能过70%
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=2e5+10;
int a[N];
signed main()
{
int n,m;cin>>n>>m;
int k=n+m+1;
for(int i=1;i<=k;i++)cin>>a[i];
sort(a+1,a+k+1);
int ans=0;
//如果没有减号直接相加即可
if(m==0)
{
for(int i=1;i<=k;i++)
ans+=a[i];
}
else
{
//最大值 - 最小值 其余的所有负数全部变为正数相加形式
ans=a[k]-a[1];
for(int i=2;i<k;i++)
{
ans+=abs(a[i]);
}
}
cout<<ans<<endl;
return 0;
}