二维矩阵和
二维前缀和,前缀和即当前元素与之前的元素之和,例如现有一个3行4列的矩阵
定义:本例中x和y从1开始,例如:(1, 1)的值为6,(2, 1)的值为7

(1, 1)的前缀和即1 + 2 + 5 + 6 = 14

-
依次计算(0, 0)、(0, 1)、(1, 0)的前缀和
- (0, 0)
-
(0, 1)
-
(1, 0)
-
根据上面的结果,计算(1, 1)的前缀和
(0, 1)的前缀和的值为3(红色矩形中的值相加)
(1, 0)的前缀和的值为6(蓝色矩形中的值相加)
计算(1,1)前缀和的值只需将红色矩形(0, 1)的前缀和值加上蓝色矩形(1, 0)的前缀和值,然后减去这两个矩形重叠的部分的前缀和的值(因为(0, 1)和(1, 0)的前缀和的包含了(0, 0),也就是(0, 0)的前缀和值被多加了一遍,所以需要减去),再加上(1,1)处的值即可计算出(1, 1)的前缀和值
3(红色矩形) + 6(蓝色矩形) - 1(重叠的部分) + 6(自身的值) = 14
所以可以得出递推公式:DP(x, y) = DP(x - 1, y) + DP(x, y - 1) - DP(x - 1, y - 1) + M(x, y)
#include <iostream> int M, N; int Martix[101][101]; int DP[101][101]; int main() { std::cin >> M >> N; for (int i = 1; i <= M; ++i) { for (int j = 1; j <= N; ++j) { std::cin >> Martix[i][j]; } } for (int i = 1; i <= M; ++i) { for (int j = 1; j <= N; ++j) { DP[i][j] = DP[i - 1][j] + DP[i][j - 1] - DP[i - 1][j - 1] + Martix[i][j]; } } printf("前缀和:\n"); for (int i = 1; i <= M; ++i) { for (int j = 1; j <= N; ++j) { printf("%d ", DP[i][j]); } printf("\n"); } return 0; } /* input: 3 4 1 2 3 4 5 6 7 8 9 10 11 12 output: 1 3 6 10 6 14 24 36 15 33 54 78 */