ural 1146 Maximum Sum 最大连续和

1146. Maximum Sum

Time limit: 0.5 second

Memory limit: 64 MB

Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. 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. A sub-rectangle is any contiguous sub-array of size 1 × 1 or greater located within the whole array.

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-hand corner and has the sum of 15.

Input

The input consists of an N × N array of integers. The input begins with a single positive integer Non a line by itself indicating the size of the square two dimensional array.
This is followed by N 2integers separated by white-space (newlines and spaces). These N 2 integers
make up the array in row-major order (i.e., all numbers on the first row, left-to-right, then all numbers on 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

The output is the sum of the maximal sub-rectangle.

Sample

input output
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
15

题意:给个n*n的矩阵,所有子矩阵中 ,和最大等于多少。

做法:

首先要理解一个O(n)的算法 。

给一个数组  求连续和的最大值。 可以用一个sum来从下标0开始计算和,不断取最大值。当加和小于0的时候 初始化为0;

如 3 -4 5 1 -2    第一个步加和是3,再加上第二个-4 ,sum就变成-1了,所以要初始化sum为0,再加5 ,再加1, 最后得到最大值为6。

然后对于矩阵,我们可以先预处理,sum[ i ] [ j ]为 第 i 列的 前j项和;

然后枚举 两列 i,j  ,然后k表示行 从1到n。  那么sum[ k ][ j ] -sum [ k ][ i - 1 ]  就是k行 i列到j列的和,可以看作是一个点的值,就和上面讲的一样,一点点加过来,然后遇到负值初始化为0 就可以了。最后的最大值 就是答案了。

暴力: 预处理了 sum数组,预处理 sum[ i ][ j ]= (0,0) 到(i,j)的和。然后枚举矩阵中任意两点,求最大和。 复杂度是10^8/4  也就是 2*10^7次,也可以ac。

#include<stdio.h>
#include<string.h>

int sum[110][110];
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		memset(sum,0,sizeof sum);
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=n;j++)
			{
				int a;
				scanf("%d",&a);
				sum[i][j]=sum[i][j-1]+a;
			}
		}
		int ans=-1000000000;
		for(int i=1;i<=n;i++)
		for(int j=i;j<=n;j++)//j>=i
		for(int k=1,tem=0;k<=n;k++)
		{
			tem+=sum[k][j]-sum[k][i-1];
			ans=ans>tem?ans:tem;
			if(tem<0) tem=0;
		}
		printf("%d\n",ans);
	}
	return 0;

}
//暴力
#include <stdio.h>
#include <math.h>
#include <algorithm>
using namespace std;

int sum[110][110];
int a[110][110];
int main()
{
	int n;
	//freopen("output.txt","w",stdout);
	while(~scanf("%d",&n))
	{
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				scanf("%d",&a[i][j]);
				int tem=a[i][j];
				if(i!=0)
					tem+=sum[i-1][j];
				if(j!=0)
					tem+=sum[i][j-1];
				if(i!=0&&j!=0)
					tem-=sum[i-1][j-1];
				sum[i][j]=tem;
				//printf("%d  ",tem);
			}
			//puts("");
		}

		int flag=1;
		int maxx;
		for(int i=0;i<n;i++)
		for(int j=0;j<n;j++)
		for(int k=0;k<=i;k++)
		for(int l=0;l<=j;l++)
		{
			int tem=0;
			tem+=sum[i][j]; 

			if(k!=0)
			tem-=sum[k-1][j];
			if(l!=0)
			tem-=sum[i][l-1];
			if(l!=0&&k!=0)
			tem+=sum[k-1][l-1]; 

			if(tem==11)
				int aa=2;
			if(flag)
			{
				maxx=tem;
				flag=0;
			}
			else
				maxx=max(maxx,tem);
		}
		printf("%d\n",maxx);
	}
	return 0;
} 

/*

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

5
1 1 1 1 1
1 1 1 1 1
1 1 -99 1 1
1 1 1 1 1
1 1 1 1 1
*/
时间: 2024-10-11 12:15:37

ural 1146 Maximum Sum 最大连续和的相关文章

最大子矩阵和 URAL 1146 Maximum Sum

题目传送门 1 /* 2 最大子矩阵和:把二维降到一维,即把列压缩:然后看是否满足最大连续子序列: 3 好像之前做过,没印象了,看来做过的题目要经常看看:) 4 */ 5 #include <cstdio> 6 #include <iostream> 7 #include <cstring> 8 #include <algorithm> 9 using namespace std; 10 11 const int MAXN = 1e2 + 10; 12 co

URAL 1146 Maximum Sum(最大子矩阵的和 DP)

Maximum Sum 大意:给你一个n*n的矩阵,求最大的子矩阵的和是多少. 思路:最开始我想的是预处理矩阵,遍历子矩阵的端点,发现复杂度是O(n^4),就不知道该怎么办了.问了一下,是压缩矩阵,转换成最大字段和的问题. 压缩行或者列都是可以的. 1 int n, m, x, y, T, t; 2 int Map[1010][1010]; 3 4 int main() 5 { 6 while(~scanf("%d", &n)) 7 { 8 memset(Map, 0, siz

URAL 1146. Maximum Sum(求最大子矩阵和)

题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1146 1146. Maximum Sum Time limit: 0.5 second Memory limit: 64 MB Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. The sum of a rectangle is

ural 1146. Maximum Sum

1146. Maximum Sum Time limit: 0.5 secondMemory limit: 64 MB Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. The sum of a rectangle is the sum of all the elements in that rectangle. In this p

Ural 1146 Maximum Sum(DP)

题目地址:Ural 1146 这题是求最大子矩阵和.方法是将二维转化一维. 首先用n*n的方法来确定矩阵的列.需要先进行预处理,只对每行来说,转化成一维的前缀和,这样对列的确定只需要前后两个指针来确定,只需要用前缀和相减即可得到.前后两个指针用n*n的枚举. 确定好了哪几列,那么再确定行的时候就转化成了一维的最大连续子序列的和.再来一次O(n)的枚举就可以. 这样,总复杂就变成了O(n^3),对于n为100来说,已经足够了. 代码如下: #include <iostream> #include

Timus 1146. Maximum Sum

1146. Maximum Sum Time limit: 0.5 secondMemory limit: 64 MB Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. The sum of a rectangle is the sum of all the elements in that rectangle. In this p

UVa 108 - Maximum Sum(最大连续子序列)

题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&page=show_problem&problem=44  Maximum Sum  Background A problem that is simple to solve in one dimension is often much more difficult to solve in more th

UVA108 - Maximum Sum(最大连续和)

题意:从一个n*n的矩阵中找出和最大的子矩阵 思路:最大连续和的求解.我们可以将二维的转化为一维进行计算.sum[i][j]表示以(1, 1)和(i, j)为对角的矩阵的和.之后只要逐个枚举每个可能出现的值,保存最大值即可. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int INF = 0x3

Poj 2479 Maximum sum【双向DP/最大连续和】

Maximum sum 题意:给定一个长度为N的数组,求两个连续的子序列,使得两个连续子序列的和最大. 分析:乍一看,跟最大连续和有点类似,但是,又有区别,因为对于这个题,考虑第i项两个连续子序列的最大和,不能仅仅由前i-1项递推得出,第i项两个连续子序列的最大和,与前i项和i以后的之间是存在关系的,因此这个题目是一个双向dp. 假如给定的序列为a0, a1, a2, a3, a4, ...... ,an,那么,对于任意第i项,我以第i个元素为分界点,用一个数组项pMax [i]来保存  区间