ZOJ1074-DP

求一个N*N的矩阵中最大和的子矩阵

简单的一维的n个数的序列求连续最大和很好想:

如果前缀大于零肯定要加上,如果小于就没必要加了

二维的也一样,因为N很小,所以可以通过枚举开始行和结束行降维成一维

原始表
a00 a01 a02 a03 a04
a10 a11 a12 a13 a14
a20 a21 a22 a23 a24
a30 a31 a32 a33 a34
a40 a41 a42 a43 a44

如上表:先枚举起始行为0的(结束行为0~n)

用b数组记录降维后的状态

起始行为0

                  结束行为0

a00 a01 a02 a03 a04
b0 = a00 b1 = a01 b2 = a02 b3 = a03 b4 = a04

                 结束行为1

a00 a01 a02 a03 a04
a10 a11 a12 a13 a14
b0 = a00+a10 b1 = a01+a11 b2 = a02+a12 b3 = a03+a13 b4 = a04+a14

               等等等等

这样算每一个b数组的最大值,再求出最大值就是答案了

这样枚举起始行i和结束行jO(n^{2})复杂度算出b数组O(n^{2})复杂度太高

优化:起始行为i,结束行为i算出b数组不要清空,接着算结束行为(i+1)的结果,整体复杂度降为O(n^{3})(我不说你们也知道怎么优化,但是我就不知道,最后看的书,我的脑子真的快成浆糊了,哭唧唧)

#include 
#include 
#include 
using namespace std;

const int maxn = 100;
int a[maxn+5][maxn+5], b[maxn+5];

int main()
{
	int n;
	int ans = -10000000;	//最小不会小于-127 * 100 * 100 
	scanf("%d", &n);		//input
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j  ans)	ans = sum;//更新 
			}
		}
	}
	printf("%d\n", ans);
	return 0;
 } 

 

你可能感兴趣的:(脚踏实地)