hihoCoder: 矩阵游戏II

题目2 : 矩阵游戏II
时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定一个NxN的整数矩阵,小Hi每次操作可以选择两列,将这两列中的所有数变成它的相反数。

小Hi可以进行任意次操作,他的目标是使矩阵中所有数的和尽量大。你能求出最大可能的和吗?
输入

第一行一个整数N。

以下N行,每行N个整数Aij。

对于30%的数据,2 ≤ N ≤ 10

对于100%的数据,2 ≤ N ≤ 200, -1000 ≤ Aij ≤ 1000
输出

最大可能的和
样例输入

4
-1 1 1 2 
-2 -3 1 2  
-3 -2 1 2  
-4 -1 1 2

样例输出

27

思路

一列数的和翻转后就是原来和的 -1倍,我们先把所有和为负数的列都翻转为正数并记下原来有多少列为负的,如果负数列为偶数那么总和就是答案,如果是奇数列那么就会有一个负数列出现,因为我们之前把这个负数列也变成正数加上去了所以我们需要减去两倍的这个负数列,接下来就是这个负数列怎么定,我原来只是在矩阵的负数列中找,后来发现绝对值最小的不一定在其中,我们可以把落单的那个负数列和正数中绝对值最小的那一列翻转。

import java.util.*;

public class Main {
    static int RolSum(int[][] n, int i) {//返回每一列的和
        int sum = 0;
        for (int j = 0; j < n.length; j++) {
            sum += n[j][i];
        }
        return sum;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int N = in.nextInt();
        int[][] n = new int[N][N];
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                n[i][j] = in.nextInt();
            }
        }
        int sum = 0;
        int min = 1001;
        int k = 0;
        for (int i = 0; i < N; i++) {
            int b = RolSum(n, i);//等于当前列的和
            if (b < 0) k++;//我们需要记录和小于0的列的数量
            if (a < min) min =  Math.abs(b);;//记录绝对值最小的数
            sum += Math.abs(a);//在总和里加绝对值
        }
        if (k % 2 == 1) {如果和为负数的列是奇数,那么我们需要减去绝对值最小的列的两倍的值。
            sum -= min * 2;
        }
        System.out.print(sum);
    }
}

你可能感兴趣的:(java)