前缀和(二维)

前言

前面介绍了一维前缀和,二维前缀和是一维前缀和的在线升级,一维前缀和体现在数组,而二位前缀和体现在矩阵上。


一、什么是二维前缀和?

基于立在一维前缀和的基础上,现在所求是矩阵内一个任意的子矩阵的数的和,这样的问题我们就可以用二维前缀和进行求解。

二、二维前缀和讲解

引入

对于一个矩阵
例如:定义一个矩阵g[n][m]

const int n=3,m=4;
int g[n][m]={
   {
   1,5,6,8},{
   9,6,7,3},{
   5,3,2,4}};
g[n][m]
1   5   6   8
9   6   7   3
5   3   2   4
 (1) 求矩阵(1,1)到(2,2)的和
 (2) 求矩阵(0,1)到(1,3)的和

我们最容易想到的就是暴力枚举法
即:
问题(1) 6+7+3+2=18
问题(2) 5+6+8+6+7+3=35
其复杂度是O(nm) 如果矩阵短小还好 但当数据过大时这种办法就有些不时限了,所以我们引入二维的前缀和是其复杂度降低。

思路

如果我们将这个3*4的矩阵看成一个大长方形
对于问题(1)我们可以有另一种解法
前缀和(二维)_第1张图片
<<凑活看吧第一次插入图片还没搞懂>>
(阴影为所求)
解法就是:所求阴影=大长方形-(1)-(2)+(3);
结合g[n][m]矩阵,我们进一步分析
找出矩阵g[1],g[2],g[3]

矩阵g[1]                  
1   5   6   
9   6   7   
5   3   2   
矩阵g[2]     矩阵g[3]
1            1   5   6   
9 
5
问题(1)  就可解为:g[1]-g[2]-g[3]+1
现在的问题的就是该如何求矩阵的和了
我们此时引入二维前缀和sum[i][j]
sum[i][j]就是从(0,0)到(i,j)的矩阵和

这样就更好解了
问题(1)=sum[3][3]-sum[2][0]-sum[0][2]+sum[0][0];
由g[n][m] 可以求得sum[n][m]

sum[n][m]
1   6   12   20
10  

你可能感兴趣的:(算法,c语言,算法,c++)