总时间限制:
内存限制:
-
已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵。
比如,如下4 * 4的矩阵
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩阵是
9 2
-4 1
-1 8
这个子矩阵的大小是15。 - 输入是一个N * N的矩阵。输入的第一行给出N (0 < N <= 100)。再后面的若干行中,依次(首先从左到右给出第一行的N个整数,再从左到右给出第二行的N个整数……)给出矩阵中的N 2个整数,整数之间由空白字符分隔(空格或者空行)。已知矩阵中整数的范围都在[-127, 127]。
- 输出最大子矩阵的大小。
-
4 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2
-
15
描述
输入
输出
样例输入
样例输出
题目大概:
输入一个由数字组成的n*n矩阵,找出其中的最大子矩阵,即子矩阵的和最大。
思路:
一般都会想到穷举法,把所有的子矩阵全列出来,但这种方法需要控制四个循环,太麻烦。所以可以把它转变为求最大子段和问题,即转变为一维问题。
就是可以把矩阵的每一列的数加在一起,这个矩阵就变成了一行,如果求出这一行数的最大子段和就是这个矩阵的最大子矩阵,这样就只需要控制行数,不需要控制列的变化,
就简单了许多。
最大子段和的求法,若c为这个字段的和a[n]为第n个数,1... c<0 则舍去c,c=a[n]。
2...c>=0 c=c+a[n]。
感想:
dp题有时候是需要转化的。
代码:
#include <iostream>
using namespace std;
int main()
{int n,m=0;
int a[101][101];
cin>>n;
for(int i=1;i<=n;i++)
{for(int t=1;t<=n;t++)
{cin>>a[i][t];}
}
for(int i=1;i<=n;i++)
{int b[101]={0};
for(int t=i;t<=n;t++)
{
for(int l=1;l<=n;l++)
{b[l]=b[l]+a[t][l];
}
int c=0,ma=0;
for(int y=1;y<=n;y++)
{if(c>0)c=c+b[y];
else c=b[y];
if(c>ma)ma=c;
}
if(m<ma)m=ma;
}
}
cout<<m;
return 0;
}