Description
给出一个N*N矩阵,找出部分和最大的子矩阵
Input
一个正整数n(n<=100),接下来n*n个整数表示矩阵每个点的值
Output
其子矩阵的最大部分和
Sample Input
4
0 -2 -7 0 9 2 -6 2
-4 1 -4 1 -1
8 0 -2
Sample Output
15
Solution
水题,因为是二维矩阵,所以直接暴搜时间复杂度是O(n^4),因此对列元素用前缀和存储,然后暴力枚举子矩阵起始列终止列可以将时间复杂度降为O(n^3)
Code
#include<cstdio>
#include<iostream>
using namespace std;
#define maxn 102
int dp[maxn][maxn];
int n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
int d;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&d);
dp[i][j]=dp[i-1][j]+d;//对列元素用前缀和存储
}
int ans=-1;
for(int j=1;j<=n;j++)//枚举子矩阵起始列终止列
for(int i=j;i<=n;i++)
{
int sum=0;
for(int k=1;k<=n;k++)
{
int t=dp[i][k]-dp[j-1][k];
sum+=t;
if(sum<0)//如果和小于零还不如一个元素都不加
sum=0;
if(sum>ans)//更新最大部分和
ans=sum;
}
}
printf("%d\n",ans);
}
return 0;
}