1. 程式人生 > 其它 >AcWing 126. 最大的和(二維字首和)

AcWing 126. 最大的和(二維字首和)

技術標籤:題解AcWingc語言c++

題目連結

給定一個包含整數的二維矩陣,子矩形是位於整個陣列內的任何大小為1 * 1或更大的連續子陣列。

矩形的總和是該矩形中所有元素的總和。

在這個問題中,具有最大和的子矩形被稱為最大子矩形。

例如,下列陣列:

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,表示方形二維陣列的大小。

從第二行開始,輸入由空格和換行符隔開的N2個整數,它們即為二維陣列中的N2個元素,輸入順序從二維陣列的第一行開始向下逐行輸入,同一行資料從左向右逐個輸入。

陣列中的數字會保持在[-127,127]的範圍內。

輸出格式

輸出一個整數,代表最大子矩形的總和。

資料範圍

1≤N≤100

輸入樣例:

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

8  0 -2

輸出樣例:

15

思路:

列舉矩形的對頂角左邊,需要四重迴圈,再用二維字首和在O(1)的時間內求出矩形的和,總的複雜度是O(n^4)。參考下一維連續和的問題,若dp[i]為以i為結尾的最大連續和,則當dp[i-1] > 0時,dp[i]就需要加上dp[i - 1],否則不加。現在將矩形的每一列抽象為一維連續和問題的一個數,之前的若干列和為正數,就加上它,否則不加。需要列舉列所在的起點和終點,以及橫向的一層遍歷,總的複雜度為立方級別的。

答案:

#include <iostream>
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define INF 0x3f3f3f3f3f3f3f3f
#define rep(i,a,b) for(auto i=a;i<=b;++i)
#define bep(i,a,b) for(auto i=a;i>=b;--i)
#define lowbit(x) x&(-x)
#define PII pair<int,int>
#define
PLL pair<ll,ll>
#define PI acos(-1) #define pb push_back #define eps 1e-6 const int mod = 1e9 + 7; const int N = 1e5 + 10; const int M = 1e3 + 10; using namespace std; int dp[M][M]; void solve(){ int n; cin>>n; rep(i,1,n){ rep(j,1,n){ cin>>dp[i][j]; dp[i][j]+=dp[i-1][j]; ///列字首和 } } int maxn=INT_MIN; rep(i,1,n){ rep(j,i,n){ int res=0; rep(k,1,n){ res+=dp[j][k]-dp[i-1][k]; if(res>maxn) maxn=res; if(res<0) res=0; } } } cout<<maxn<<endl; } int main() { solve(); return 0; }