codeforces 构造 Yaroslav and Sequence

题目描述:

题目大意:有 2n - 1个数, 在一次操作中,你可以任意改变其中 n 个数的正负号,你可以进行任  何多次的操作,求这 2n - 1 个数字所能达到的最大和。

算法思想:

        这道题竟然是和 n 的奇偶性相关的。

        假如 n 是偶数,假设某次操作前,已经改变了 x 数的正负号, 还有 y 个数正负号 没有发生变化,x + y = 2n - 1。那么进行一次变化中,你可以选中 a 个已经改变了的数再次改变其符号,选取b 个没有改变的数改变其符号,那么改变了的数 减少 a 个,又增加 b 个,即增加 b - a 个,又因为b + a = n, 所以 b - a 必定为偶数,即改变符号的数在一次操作中只能减少或增加偶数个。假如我们有偶数个负数,那么我们可以把这偶数个负数全部变为相反数,假如我们有奇数个负数,那么最有情况下,最后一定会剩下一个最大的负数。

        假如 n 是奇数,同理, b - a 必定为奇数,即改变符号的数在一次操作中只能减少或增加奇数个,那么我们可以控制可以每次增加或减少一个,也就是所有数的正反号都可以确定。这种情况下,就是所有数的绝对值和。

AC代码:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
 
int main()
{
    int n, sum = 0, neg = 0, mn = 2000;
    cin >> n;
 
    for (int i = 0; i < 2 * n - 1; i++) {
        int d;
        cin >> d;
        sum += abs(d);
        if (d < 0) neg++;
        mn = min(mn, abs(d));
    }
 
    if (n%2==0 && neg%2==1) sum -= 2 * mn;
 
    cout << sum << endl;
 
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值