HDU1081:To The Max(最大子矩阵,线性DP)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=1081

自己真够垃圾的,明明做过一维的这种题,但遇到二维的这种题目,竟然不会了,我也是服了(ps:猪啊)。

最终还是看了题解。

代码如下:

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int n,w[110][110],t;
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        memset(w,0,sizeof(w));
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
               scanf("%d",&t);
               w[i][j]+=w[i][j-1]+t;
            }
        }
        int maxx=-inf;
        for(int i=1;i<=n;i++)
        {
            for(int j=i;j<=n;j++)
            {
                int sum=0;
                for(int k=1;k<=n;k++)
                {
                    if(sum<0) sum=0;
                    sum+=w[k][j]-w[k][i-1];
                     if(sum>maxx)
                        maxx=sum;
                }
            }
        }
        printf("%d
",maxx);
    }
    return 0;
}

大神的题解:

这一题就是将一维的最大字段和扩展到二维,在一维的求最大字段和的过程中是这样操作的:

int max_sum(int n)
{
    int i, j, sum = 0, max = -10000;
    for(i = 1; i <= n; i++)
    {
        if(sum < 0)
            sum = 0;
        sum += a[i];
        if(sum > max)
            max = sum;
    }
    return sum;
}
扩展到二维的时候也是同样的方法,不过需要将二维压缩成一维,所以我们要将数据做一下处理,使得map[i][j]从表示第i行第j个元素变成表示第i行前j个元素和,这样map[k][j]-map[k][i]就可以表示第k行从i->j列的元素和。只要比一维多两层循环枚举i和j就行了。
#include <iostream>
#define MAX 101
using namespace std;
int map[MAX][MAX];
int main()
{
    int n, i, j, temp, k;
    
    while(scanf("%d", &n) != EOF)
    {
        memset(map, 0, sizeof(map));
        for(i = 1; i <= n; i++)
            for(j = 1; j <= n; j++)
            {
                scanf("%d", &temp);
                map[i][j] += map[i][j - 1] + temp;//这里表示第i行的前j列之和
            }
        int max = -100000;
        for(i = 1; i <= n; i++)
            for(j = i; j <= n; j++)
            {
                int sum = 0;
                for(k = 1; k <= n; k++)
                {
                    if(sum < 0)
                        sum = 0;
                    sum += map[k][j] - map[k][i  - 1];//这里表示前k行,i->j列之和
                    if(sum > max)
                        max = sum;
                }
            }
        printf("%d
", max);
    }
return 0;
}
原文地址:https://www.cnblogs.com/zhangmingcheng/p/4381346.html