hud 1559 最大子矩阵

 用暴力查找会超时。

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

例如:

 1
 4 5 2 3
3361
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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值