洛谷P1719 最大加权矩形 (最大子数组和 加强版)
P1719 最大加权矩形
先给一个 n×n 矩阵,1 <= n <= 127。要求矩阵中最大加权矩形,即矩阵的每一个元素都有一权值,权值定义在整数集上。
从中找一矩形,矩形大小无限制,是其中包含的所有元素的和最大 。矩阵的每个元素属于 [-127,127],
例如
0 –2 –7 0
9 2 –6 2
-4 1 –4 1
-1 8 0 –2
在左下角:
9 2
-4 1
-1 8
和为 15。
需要先进行一个矩阵压缩,即二维变一维。
矩阵压缩的精髓,将每一列的数进行相加,将多行变为一行。
先算第 1 行序列最大子数组和,然后算第1 ,2行序列相加的序列最大子数组和,然后算第1 ,2,3行序列相加的序列最大子数组和,......,然后算第1 ,2,3,...,n行序列相加的序列最大子数组和
先算第 2 行序列最大子数组和,然后算第2 ,3行序列相加的序列最大子数组和,然后算第2 ,3,4行序列相加的序列最大子数组和,......,然后算第2,3,...,n行序列相加的序列最大子数组和
......
#include <iostream>
using namespace std;
#include <algorithm>
int n;
//求最大子数组和
int getMaxSum(int nums[]){
int res = nums[0],sum = 0;
for(int i = 0;i < n;i++){
if(sum > 0) sum += nums[i];
else sum = nums[i];
res = max(res,sum);
}
return res;
}
int main(){
cin >> n;
int nums[n][n];
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++)
cin >> nums[i][j];
}
int maxRes = -1000;
int sum[n];
for(int i = 0;i < n;i++){
for(int j = 0;j < n;j++) sum[j] = nums[i][j];//这里的j只是为了初始化新一轮的sum数组
maxRes = max(maxRes,getMaxSum(sum));
for(int j = i + 1;j < n;j++){
for(int k = 0;k < n;k++){
sum[k] += nums[j][k]; //这里的k是为了控制sum数组与新一行nums数组累加
}
maxRes = max(maxRes,getMaxSum(sum));
}
}
cout << maxRes;
}