練習題:最大子陣
給定一個 n×m的矩陣 A,求 A 中的一個非空子矩陣,使這個子矩陣中的元素和最大。其中,A的子矩陣指在 A 中行和列均連續的一部分。
輸入格式
輸入的第一行包含兩個整數 n,m(1≤n,m≤50),分別表示矩陣 A 的行數和列數。
接下來 n 行,每行 m 個整數,表示矩陣 Ai,j(−1000≤Ai,j≤1000)。
輸出格式
輸出一行,包含一個整數,表示 A 中最大子矩陣的元素和。
樣例輸入
3 3
2 -4 1
-1 2 1
4 -2 2
樣例輸出
6//最大子陣
// 將最大子陣問題轉換為最大子段和問題,最大子段和,如(a1,a2,a3,a4,a4,a6)=(-1,11,-1,13,-5,-2)時,最大子段和就為23。
// 將矩陣每一列都加在一起,就形成了一個一維陣列 ,如(ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
// 列舉正確的行組合,然後在依次列舉其轉換為一維數組裡的元素和,求出最大子段和即為最大子陣。
#include<stdio.h>
#include<string.h>
int dp[100];
int getMaxArray(int a[],int n);
int main()
{
int n,m,i,j,k;
scanf("%d%d",&n,&m);
int a[n][m];
for(i=0;i<n;i++)
for(j=0;j<m;j++)
scanf("%d",&a[i][j]);
int res=a[0][0],tmp;
for(i=0;i<n;i++)
{
memset(dp,0,sizeof(dp));//memset函式:將dp陣列全部成員初始化為0;
for(j=i;j<n;j++) //列舉所有行的組合;
{
for(k=0;k<m;k++)
{
dp[k]+=a[j][k];//將相應的列元素加在一起,使其變為一維陣列;
}
tmp=getMaxArray(dp,m);
res=res>tmp?res:tmp;
}
}
printf("%d\n",res);
return 0;
}
int getMaxArray(int a[],int n)
{
int max=a[0],temp=0,i;
for(i=0;i<n;i++)
{
if(temp>0) //如果temp為負則重新賦值;
temp+=a[i];
else
temp=a[i];
max=max>temp?max:temp;
}
return max;
}