AcWing寒假每日一题——Day22最大的和

最大的和

给定一个包含整数的二维矩阵,子矩形是位于整个阵列内的任何大小为 1 ∗ 1 1 * 1 11或更大的连续子阵列。

矩形的总和是该矩形中所有元素的总和。

在这个问题中,具有最大和的子矩形被称为最大子矩形。

例如,下列数组:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
其最大子矩形为:
9 2
-4 1
-1 8
它拥有最大和15

输入格式
输入中将包含一个 N ∗ N N*N NN的整数数组。

第一行只输入一个整数 N N N,表示方形二维数组的大小。

从第二行开始,输入由空格和换行符隔开的 N 2 N^2 N2个整数,它们即为二维数组中的 N 2 N^2 N2个元素,输入顺序从二维数组的第一行开始向下逐行输入,同一行数据从左向右逐个输入。

数组中的数字会保持在 [ − 127 , 127 ] [-127,127] [127,127]的范围内。

输出格式
输出一个整数,代表最大子矩形的总和。

数据范围
1 ≤ N ≤ 100 1≤N≤100 1N100
输入样例:

4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

输出样例:

15

分析: 此题的模型可以转换为一维求连续数组最大的和。
枚举每个子矩阵,用求连续数组最大的和的方式来求。
先看一维数组最大的和怎么求:
给定数组 a 1 , a 2 , . . . . , a n a_1,a_2,....,a_n a1,a2,....,an
可以将集合划分成两部分( a a a数组的意义为以 i i i结尾的区间): f ( i ) = { a [ i ] , i = 1 m a x ( a [ i ] , a [ i ] + f ( i − 1 ) ) , i > 1 f(i)=\begin{cases} a[i],i=1 \\ max(a[i],a[i]+f(i-1)),i>1 \end{cases} f(i)={ a[i],i=1max(a[i],a[i]+f(i1)),i>1
可以把 i > 1 i>1 i>1的情况中的 a [ i ] a[i] a[i]提出来。得 a [ i ] + m a x ( 0 , f ( i − 1 ) ) a[i]+max(0,f(i-1)) a[i]+max(0,f(i1))

那么扩展到二维,就需要把每一列的和求出来,所以我们用前缀和。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=105;
int a[N][N],n,x;
int main(){
    
    
    cin>>n;
    for(int i=1;i<=n;i++){
    
    
        for(int j=1;j<=n;j++){
    
    
            cin>>x;
            a[i][j]=a[i-1][j]+x;
        }
    }
    int res=-127;
    for(int i=1;i<=n;i++){
    
    
        for(int j=i;j<=n;j++){
    
    
            int f=0;
            for(int k=1;k<=n;k++){
    
    
                int w=a[j][k]-a[i-1][k];
                f=max(0,f)+w;
                res=max(f,res);
            }
        }
    }
    cout<<res<<endl;
}

猜你喜欢

转载自blog.csdn.net/messywind/article/details/113485529
今日推荐