POJ 1050 && HDU 1081 To the Max(前缀和)

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;
}

你可能感兴趣的:(POJ 1050 && HDU 1081 To the Max(前缀和))