51nod 1051 最大子矩陣和

2021-08-18 17:24:13 字數 1936 閱讀 2817

1051 最大子矩陣和

基準時間限制:2 秒 空間限制:131072 kb 分值: 40 

難度:4級演算法題

乙個m*n的矩陣,找到此矩陣的乙個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。

例如:3*3的矩陣:

-1 3 -1

2 -1 3

-3 1 2

和最大的子矩陣是:

3 -1

-1 3

1 2input

第1行:m和n,中間用空格隔開(2 <= m,n <= 500)。

第2 - n + 1行:矩陣中的元素,每行m個數,中間用空格隔開。(-10^9 <= m[i] <= 10^9)

output

輸出和的最大值。如果所有數都是負數,就輸出0。
input示例

3 3

-1 3 -1

2 -1 3

-3 1 2

output示例

7
思路:對於矩陣a[n][m]的最大子矩陣和,如果用暴力的話,要遍歷子矩陣的上下左右邊的位置,那麼時間複雜度為 o(n^4) ,會 tle, 因此要考慮優化,對於最大子矩陣和,肯定是要遍歷所有的子矩陣,而對於子矩陣的四邊位置,右下端的兩邊是一定要遍歷的,那麼就要考慮如何遍歷另一邊就可以找出 最大子矩陣,這樣時間複雜度就為 o(n^3)。

dp[i][j][k]:  子矩陣右下端以 i,j為邊, 高為h的最大子矩陣和    || s為 j-1->j 間綠色陰影面積

狀態轉移方程: 對於dp[i][j][k], 對dp[i][j-1][k]就行分析:

若 dp[i][j-1][k]>0:  則 dp[i][j][k]= dp[i][j-1][k]+ s

若dp[i][j-1][k]<=0: 則 dp[i][j][k]= s

綜上:dp[i][j][k]= max(dp[i][j-1][k]+s,s);

由方程知 第一維[i]可以去掉,即 dp[j][k]= max(dp[j-1][k]+s,s);

而在觀察可知 第二維 [j]也可以去掉,即  dp[k]=max(dp[k]+s,s);

而對於 面積s,可以先用字首和求出 a[1][1]到 a[i][j]的和(就儲存在 a[i][j]中。這樣s=a[i][j]-a[i][j-1]-a[i-k][j]+a[i-k][j-1]

code 1:

//二維dp 

#includeusing namespace std;

typedef long long ll;

const int max_n=505;

const int max_m=505;

int n,m;

ll a[max_n][max_m];

ll dp[max_m][max_n];

int main()

ll ans=0;

for(int i=1;i<=n;++i)

for(int k=1;k<=i;++k)

for(int j=1;j<=m;++j)

cout

//一維dp

#includeusing namespace std;

typedef long long ll;

const int max_n=505;

const int max_m=505;

int n,m;

ll a[max_n][max_m];

ll dp[max_n];

int main()

ll ans=0;

for(int i=1;i<=n;++i)

for(int k=1;k<=i;++k)

}cout<

51 nod1051 最大子矩陣和

1051 最大子矩陣和 基準時間限制 2 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 乙個m n的矩陣,找到此矩陣的乙個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。例如 3 3的矩陣 1 3 1 2 1 3 3 1 2 和最大的子矩陣是 3 1 1 3 1 2 ...

51nod1051 最大子矩陣和

1051 最大子矩陣和 基準時間限制 2 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 乙個m n的矩陣,找到此矩陣的乙個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。例如 3 3的矩陣 1 3 1 2 1 3 3 1 2 和最大的子矩陣是 3 1 1 3 1 2 ...

51nod 1051 最大子矩陣和

1051 最大子矩陣和 基準時間限制 2 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 乙個m n的矩陣,找到此矩陣的乙個子矩陣,並且這個子矩陣的元素的和是最大的,輸出這個最大的值。例如 3 3的矩陣 1 3 1 2 1 3 3 1 2 和最大的子矩陣是 3 1 1 3 1 2i...