zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    java--volatile关键字
    java--线程异常处理器
    java--线程池
    Supervisor安装和使用
    网络协议--HTTP
    1.Nginx简介
    Nginx配置实战
    Redis面试题
    SpringBoot--集成swagger2
    缓存的优缺点
  • 原文地址:https://www.cnblogs.com/zhangmingcheng/p/4381346.html
Copyright © 2011-2022 走看看