uacs2024

导航

洛谷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;
}

 

posted on 2024-11-26 18:48  ᶜʸᵃⁿ  阅读(134)  评论(0)    收藏  举报