1899: 985的最大和难题
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 291 Solved: 31
Submit Status Web Board
Description
985有2 * n - 1个整数,他每次可以将其中n个数变号,操作次数不限,问他可以得到的最大和。
Input
第一行输入一个整数t,代表有t组测试数据。
每组数据占两行,第一行输入一个整数n,下面一行输入2*n-1个整数a[]。
注:1 <= t <= 32,1 <= n <= 1e3,-1e3 <= a[] <= 1e3。
Output
输出一个整数代表可以得到的最大和。
Sample Input
221 1 12-10 20 -10
Sample Output
340
HINT
Source
对于给数,我们记录里面负数的个数ant,绝对值之和sum,和绝对值最小值minn
正数集合为x,负数集合为y:
一 :我们每次要从x集合拿a个数,y集合拿b个数,且a+b == n,那么如果n为奇数的话,y集合的负数是可以都变成正数的(方法合理即可)。
二 :如果n为偶数,那么我们只能改变偶数个数,那么就判断y集合的元素是奇数还是偶数,如果是偶数,那么也可以全部变成正数;如果是奇数,那么总有一个数不能变成正数,那么我们为了得到最优解,就让绝对值最小的为负数,sum- 2*minn即可。
代码:#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define M 200000
#define inf 0x3f3f3f3f
int a[M+10];
int main()
{
int u;
scanf("%d",&u);
while(u--)
{
int n,i,t,minn=inf;
int sum=0,ant=0;
scanf("%d",&n);
for(i=1;i<2*n;i++)
{
scanf("%d",&t);
if(t<0)
{
t=-t;
ant++; //负数个数
}
sum+=t; //总和
minn=min(minn,t);
}
if(n&1)
printf("%d\n",sum);
else
{
if(ant&1)
printf("%d\n",sum-2*minn);
else
printf("%d\n",sum);
}
}
return 0;
}