POJ-1050 To the MAX题解

题目大意:

给定一个矩阵,要求矩阵中最大子矩阵和。N<=100
如输入:
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
输出:
15

思路:

法一:这题是到数据范围不是很严谨的一道题,虽说N<=100,但是N^4仍然可以过。
复习一下二维前缀和的知识
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1];
若要求左上角为(i,j)右下角为(x,y)的矩形和则为:dp[x][y]-dp[x][j-1]-dp[i-1][y]+dp[i-1][j-1];
法二:比较精彩的方法,矩阵是可以压缩的,压缩后相当于求最大子序列和的问题(类似线性dp问题)。状态转移方程式dp[i][j][k]=max{ dp[i-1][j][k]+SUM(j,k),SUM(j,k) }; 时间复杂度为O(N^3)。

反思:两种做法都可尝试一下,第一种是复习一下前缀和的知识,第二种是dp,比较巧妙而且省空间。但第一种的复杂度应该是可以被卡的,所以此题应该重点掌握第二种dp做法。

法一代码:

#include<cstdio>
#include<algorithm>

using namespace std;
const int MAXN=100+10;
int box[MAXN][MAXN];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            scanf("%d",&box[i][j]);
               box[i][j]=box[i-1][j]+box[i][j-1]+box[i][j]-box[i-1][j-1];
        }
    }
    int ans=0;
    for(int i=1;i<=n-1;i++){
        for(int j=1;j<=n-1;j++){
            for(int k=i+1;k<=n;k++){
                for(int p=j+1;p<=n;p++){
                    ans=max(ans,box[k][p]-box[i-1][p]-box[k][j-1]+box[i-1][j-1]);//这里是二维的前缀和
                }
            }
        }
    }
    printf("%d",ans);
}

上一篇:PAT乙级1050-----螺旋矩阵 (25分)


下一篇:CI框架自定义工具函数