poj1050查找最大子矩阵和

题目:

                                      To the Max

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 48507   Accepted: 25662

Description

Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. 
As an example, the maximal sub-rectangle of the array:

0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 
is in the lower left corner:

9 2 
-4 1 
-1 8 
and has a sum of 15.

Input

The input consists of an N * N array of integers. The input begins with a single positive integer N on a line by itself, indicating the size of the square two-dimensional array. This is followed by N^2 integers separated by whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in the second row, left to right, etc. N may be as large as 100. The numbers in the array will be in the range [-127,127].

Output

Output the sum of the maximal sub-rectangle.

Sample Input

4
0 -2 -7 0 9 2 -6 2
-4 1 -4  1 -1

8  0 -2

Sample Output

  15

题意:给你一个N*N的矩阵,求该矩阵的最大子矩阵和。

子矩阵和:该子矩阵中所以元素的和。

解决方法:

  用第一个三维数组dp[k][i][j]存第k行 第i~j 列的和。 比如dp[3][1][5]表示从 "第3行第1列" 到 "第3行第5列" 的和。

  用第二个三维数组sum[k][i][j]表示"dp[1][i][j]"到"dp[k][i][j]"的和。比如sun[4][2][5]表示前4行 所有第2~5列的和。  注意:所有的数据输出从下标1开始。

  然后四层循环统计sum[k2][i][j]-sum[k1][i][j]的最大值。(1<=k1<=k2<=n)

代码:

#include <iostream>
#include <cstring>

using namespace std;

int mmap[101][101];      //存矩阵
int dp[101][101][101];   //dp[k][i][j]存第k行 第i~j列的和。 比如dp[3][1][5]表示从 "第3行第1列" 到 "第3行第5列" 的和。
int sum[101][101][101];  //sum[k][i][j]表示"dp[1][i][j]"到"dp[k][i][j]"的和。比如sun[4][2][5]表示前4行 所有第2~5列的和。  注意:所有的数据输出从下标1开始。

int n;
int main()
{
    while(cin>>n)
    {
        memset(dp,0,sizeof(dp));  //数组初始化为0
        memset(sum,0,sizeof(sum));

        //矩阵数据输入
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=n;j++)
            {
                cin>>mmap[i][j];
            }
        }

        //计算dp数组
        for(int k=1;k<=n;k++)     //k表示第k行
        {
            for(int j=1;j<=n;j++)     //因为从i~j列所以j放在i的外层
            {
                for(int i=1;i<=j;i++)
                {
                    //统计从i~j列的和
                    int sum=0;
                    for(int p=i;p<=j;p++)
                        sum+=mmap[k][p];
                    dp[k][i][j]=sum;
                }

            }
        }

        //计算sum数组
        for(int j=1;j<=n;j++)
        {
            for(int i=1;i<=j;i++)
            {
                for(int k=1;k<=n;k++)
                {
                    //对应每组 i~j 列,前k行 所有的i~j列的元素的和
                    sum[k][i][j]+=(dp[k][i][j]+sum[k-1][i][j]);
                }
            }
        }

        int mmax=-1000000;

        for(int j=1;j<=n;j++)
        {
            for(int i=1;i<=j;i++)
            {
                //对应每组i~j列,统计每组 a~b 行的最大的和。
                for(int b=1;b<=n;b++)
                {
                    for(int a=1;a<=b;a++)
                    {
                        mmax=max(mmax,sum[b][i][j]-sum[a-1][i][j]);
                    }
                }
            }
        }

        cout<<mmax<<endl;

    }
    return 0;
}

  

时间: 2024-10-24 05:28:13

poj1050查找最大子矩阵和的相关文章

最大子矩阵和问题poj1050

最大子矩阵和问题以POJ1050为例:给出一个矩阵,找出该矩阵的最大子矩阵和 例如: 0 -2 -7 0    9 2 -6 2 -4 1 -4 1 -1 8 0 -2 最大子矩阵为: 9 2 -4 1 -1 8 and has a sum of 15. 分析:首先,我们考虑一种极端的方法,如果这个数组a是一个一维数组,那么这个问题就转换成为了最大子段和问题:最大子段和b[i]=max(b[i-1]+a[i],a[i]),b[i]指的是0到i的最大子段和. #include <cstdio>

poj1050最大子矩阵和

这篇是看了别人的报告写的,就当是屡屡思路好了. 题目大意.给定一个n阶矩阵(方阵),每一个元素中存在一个数字.任务就是求出一个最大的子矩阵使得矩阵元素之间的和是最大的. n=100; 1.矩阵A[m][n]的和能够直接 sum+=A[i][j] ( i = 0 to n-1 j=0 to n-1); 还能够求出第i列的和p[i],再将所在列加起来,(当然行是同理的). 2.因此所选的矩阵的行k能够枚举(0<=k<=n-1),此时能够现将列加起来,然后找到这些列中连续最大和就可以.这就是选出的矩

最大子矩阵,最大连续子数组进阶,动态规划初级,poj1050

题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和. 例如: 这样的一个矩阵,最大子矩阵的和为15: 此题可以让人联想到求最大连续子数组,求最大子数组在上一篇文章中http://www.cnblogs.com/tz346125264/p/7560708.html. 分析:最大子矩阵可以看为求最大连续子数组拓展到二维数组上,因为矩阵的性质同样在横向竖向上需要连续,那么可以想办法将这个二维数组简化为求连续子数组. 思考: 1.要求最大子矩阵,必须保证每个矩阵都被浏览到,为了保证运行时间尽

最大子矩阵和(poj1050 动规)

题意:给出一个数字矩阵,找出一个子矩阵,使得其中的数字之和最大. 解题思路:这道题是对最大连续子串和的一种扩展.解决办法就是在二维矩阵转化为多个一维数组来求最大值.具体来说就是先固定所求子矩阵的左右边界i和j,然后求出每行从左边界到右边界的数之和,这样每行的和就可以作为一维数组的一个元素来求最大连续子串的和,这个和就是左右边界为i和j的最大矩形,枚举所有左右边界的情况,最后找出和的最大值即为最终答案. 但如果每次求左边界到右边界的和的时候一个个累加,这样时间复杂度会很大,所以这里需要用到一个二维

POJ1050 To the Max - 贪心[最大子矩阵和]

POJ1050 To the Max 传送门 题意: 给定一个\(n*n\)的带权矩阵,求一个矩阵,使矩阵内权值之和最大,输出这个矩阵的权值和.$n\leq100 $ 思路: 可以利用前缀和优化,然后\(O(n^4)\)枚举矩阵的左上角和右下角,求出最大二维前缀和. 这样的枚举方案比较难以再次优化,我们考虑矩阵权值和的实质:等价于我们将矩阵每列的权值加起来,形成一个新数列,然后对这个数列求和,而最大的矩阵权值和,相当于在矩阵上下边界不变的情况下使新数列的和最大,即新数列的最大子段和.所以换种枚举

[POJ1050]To the Max(最大子矩阵,DP)

题目链接:http://poj.org/problem?id=1050 发现这个题没有写过题解,现在补上吧,思路挺经典的. 思路就是枚举所有的连续的连续的行,比如1 2 3 4 12 23 34 45 123 234 345...然后把这些行对应列相加缩成一行,之后就是求最大子序列和了. 1 /* 2 ━━━━━┒ギリギリ♂ eye! 3 ┓┏┓┏┓┃キリキリ♂ mind! 4 ┛┗┛┗┛┃\○/ 5 ┓┏┓┏┓┃ / 6 ┛┗┛┗┛┃ノ) 7 ┓┏┓┏┓┃ 8 ┛┗┛┗┛┃ 9 ┓┏┓┏┓┃

poj1050(最大子矩阵和)

设a[i][j]表示将矩阵压缩成线性序列的前缀和 那么我们在做dp时枚举起点 i 与终点j 最内层枚举行号,那么可以一行一行的累加, 最后更新答案即可 #include<cstdio> #include<algorithm> using namespace std; const int nil=-(1<<29); const int maxn=100; int sum[maxn][maxn]; int main(){ int n; scanf("%d"

POJ1050:To the max

poj1050:http://poj.org/problem?id=1050 * maximum-subarray 问题的升级版本~ 本题同样是采用DP思想来做,同时有个小技巧处理:就是把二维数组看做一维数组.怎么去看呢,我们可以吧具有同样列号的数捆绑到一起,比如 a[1][1], a[2][1], a[3][1].....我们可以吧他们都看做 'a[1]'.因为最终的解是矩阵行数n中的任意一段,比如说:第p行到第q行, (1<=p<=q<=n), 我们要得到最终解,就一定要逐一枚举p,

最大子矩阵和问题归纳总结

一,最大子矩阵问题: 给定一个n*n(0< n <=100)的矩阵,请找到此矩阵的一个子矩阵,并且此子矩阵的各个元素的和最大,输出这个最大的值. Example: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 其中左上角的子矩阵: 9 2 -4 1 -1 8 此子矩阵的值为9+2+(-4)+1+(-1)+8=15. 二,分析 子矩阵是在矩阵选取部份行.列所组成的新矩阵. 我们首先想到的方法就是穷举一个矩阵的所有子矩阵,然而一个n*n的矩阵的子矩阵的个数当n比较大