【hihoCoder】#1615 : 矩阵游戏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

/

分析:对于一组数,他们的相反数之和是他们和的相反数。所以对于N*N矩阵,把某一列设置为相反数后求总和,实际上可以改为把某一列的和设置为相反数后求总和。

这里要求一次把某两列设置为相反数,可以先将矩阵所有列的和保存在一个vector之中,然后对vector排序。此时可以确定排序后的容器,前两个元素必然是矩阵中列之和最小的两个列。如果这两个元素相加之和小于0,那么可以确定把这两列设置为相反数后其和大于0,即可以增加矩阵的总和。将这两列设置为相反数之和,重新排序容器,继续上一步的判断,直到最小的两个元素之和大于0,意味着此时如果设置某两列为相反数,只会减小就矩阵的总和,则停止循环,获取此时容器中所有元素的和,既是矩阵可能的最大的和。

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int getcolsum(int **p, int N, int col)	//获取矩阵列的和 
{
	int sum = 0;
	for(int i = 0; i != N; ++i)
	{
		sum += p[i][col];
	}
	return sum;
}
int main()
{
	int N;
	cin >> N;
	//开辟二维数组 
	int **arr = new int*[N];
	for(int i = 0; i != N; ++i)
	{
		arr[i] = new int[N];
		for(int j = 0; j != N; ++j)	//输入元素 
			cin >> arr[i][j];
	}
	vector<int> colsum;	//获取矩阵每一列的和 
	for(int i = 0; i != N; ++i)
		colsum.push_back(getcolsum(arr, N, i));
	sort(colsum.begin(), colsum.end());	//对每一列和进行排序 
	
	while(colsum[0] + colsum[1] < 0)	//当排序后最小的两列和相加小于0,此时把这两列设置为相反数可以 
	{	//增大矩阵和,把此两列设置为相反数,即把列之和设置为相反数 
		colsum[0] = -colsum[0];
		colsum[1] = -colsum[1];	
		sort(colsum.begin(), colsum.end());		//从新排序继续循环 
	}
	//获取矩阵和 
	int sum = 0;
	for(int i = 0; i != colsum.size(); ++i)
		sum += colsum[i];
	cout << sum << endl;
	//释放二维数组 
	for(int i = 0; i != N; ++i)
		delete []arr[i];
	delete []arr;
	return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值