uacs2024

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

统计

洛谷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   ᶜʸᵃⁿ  阅读(43)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示