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)。output第2 - n + 1行:矩陣中的元素,每行m個數,中間用空格隔開。(-10^9 <= m[i] <= 10^9)
輸出和的最大值。如果所有數都是負數,就輸出0。input示例
3 3output示例-1 3 -1
2 -1 3
-3 1 2
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...