现在的位置: 首页 > 综合 > 正文

hud 1559 最大子矩阵

2019年09月07日 ⁄ 综合 ⁄ 共 1090字 ⁄ 字号 评论关闭
用暴力查找会超时。

思路:存在一些和之前计算过了就不用再计算了。

例如:

 1
 4 5 2 3

3 361
649
676
588
992
762
156
993
169
662
34
638
89
543
525
165
254
809
280

    




第1次计算(竖着)

3+992
361+762
649+156
676+933
588+169

设最大值m = 0;
第一次计算 sum = 3+992 +361+762  + 649+156

第二次计算 sum = 3+992 +361+762 +
649+156 + 676+933 - 3-922 (红色的为重复计算部分)

第三次计算 sum = 361+762+649+156+676+933+588+169-361-762

第2次计算(竖着)

992+662
762+34
156+638
933+89
169+543

第一次计算 sum = 992+662+762+34+156+638

第二次计算 sum = 992+662+762+34+156+638+922+89-992-662

第三次计算 sum = 762+34+156+638+922+89+169+543-762-34

横着和竖着的地方都有重复计算的地方,计算过的地方就可以不用一直计算,用一个数组记录。

#include <iostream>
using namespace std;
#define MAX 1001
int g[MAX][MAX];
int s[MAX];
int num, line, row, x, y;
int max(int n[])//计算每一行
{
	int i, nx, ny, m, sum;
	nx = 0;
	ny = x;
    m = 0;
	for (i=0; i<y; i++)
		m += n[i];
	sum = m;
	while (ny!=row)
	{
		m = m - n[nx] + n[ny];
		nx++;
		ny++;
		if (sum < m)
			sum = m;
	}
	return sum;
}
int main()
{
	int i, j, m, sum, nx, ny, t;
	cin>>num;
	while (num--)
	{
       cin>>line>>row>>x>>y;
	   for (i=0; i<line; i++)//记录每一列
		   for (j=0; j<row; j++)
			   scanf("%d", &g[i][j]);
	   m = 0;
	   for (j=0; j<row; j++)
	   {
		   sum = 0;
		   for (i=0; i<y; i++)
			   sum += g[i][j];
		   s[j] = sum;
	   }
	   m = max(s);
	   nx = 0;
	   ny = x;
	   for (i=0; i<line-x; i++)
	   {
		   for (j=0; j<row; j++)
			   s[j] = s[j] - g[nx][j] + g[ny][j];
		   t = max(s);
		   if (t > m)
			   m = t;
		   nx++;
		   ny++;
	   }
	   cout<<m<<endl;
	}
	return 0;
}


抱歉!评论已关闭.