1. 程式人生 > >練習題:最大子陣

練習題:最大子陣

給定一個 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;
}