Fork me on GitHub

“前缀和”思想(二哥种花生)

这两天在做OJ题,这道题主要是时间复杂度比较高,重复计算太多,需要进行时间上的优化,查阅资料用到了“前缀和”的思想,但都说的不是很清楚,发本人第一篇博客,想把这思想讲的清楚一点。


题目

  • Description
    二哥在自己的后花园里种了一些花生,也快到了收获的时候了。这片花生地是一个长度为L、宽度为W的矩形,每个单位面积上花生产量都是独立的。他想知道,对于某个指定的区域大小,在这么大的矩形区域内,花生的产量最大会是多少。
  • Input Format
    第1行有2个整数,长度L和宽度W。
    第2行至第L+1行,每行有W个整数,分别表示对应的单位面积上的花生产量A( 0≤A<10 )。
    第L+2行有2个整数,分别是指定的区域大小的长度a和宽度b。
  • Output Format
    输出一个整数m,表示在指定大小的区域内,花生最大产量为m。
  • Sample Input
    4 5
    1 2 3 4 5
    6 7 8 0 0
    0 9 2 2 3
    3 0 0 0 1
    3 3
  • Sample Output
    38

第一想法

刚看到题目觉得很简单,把矩阵存入,在循环计算进行比较就可以了,但是这样的时间复杂度过高,一个数据的重复计算太多,可以用但是会造成题目解答超时。

“前缀和”思想

“前缀和”的思想可以概括为这样子的公式:ans[i] = ans[i-1] + a[i]
其中ans需要我们区着手构建,a[i]是我们进行优化后想要的那个数值,构建好之后a[i]就可以用ans[i]-ans[i-1]来得到,这样就避免了数据的重复计算,属于用空间换时间,一般用于优化时间复杂度。

“前缀和”用于本题

可以构建一种方式来快速得到每个小矩阵的和,具体的做法为:
p[i][j] = p[i][j] + p[i-1][j] + p[i][j-1] - p[i-1][j-1]
意即:i行j列元素 = 它本身 + 左元素(如果存在)+ 上元素(如果存在)+ 左上角元素(如果存在),将输入的数据转化为一个新的矩阵。
求小矩阵和的具体做法为:
s = p[i][j] - p[i][j-b] - p[i-a][j] + p[i-a][j-b] (s为和,a、b分别为小矩阵的长和宽)
意即:小矩阵的和 = 矩阵右下角元素 - 左矩阵右下角元素(如果存在)- 上矩阵右下角元素(如果存在)+ 左上角矩阵右下角元素(如果存在),用于快速计算。

示意图如下:

代码

代码链接:SJOJ1002
1000×1000的数组过大,需要进行动态的创建数组,有点忘了,之后进行优化吧。
还有一种方法由于优化的比较好,并没有用到“前缀和”思想,比较厉害(本人其实更偏向于这种优化),链接贴在后面,有时间再研究。

参考资料

题目链接:https://acm.sjtu.edu.cn/OnlineJudge/problem/1002
“前缀和”解题:
1.https://blog.csdn.net/zhonghua123/article/details/22721361
2.https://blog.csdn.net/oscaronmar/article/details/78975867
优化算法解题:
https://blog.csdn.net/lmw21848/article/details/51072918

Tip: 由于本人第一次发博客,难免有不妥之处,望各位批评指正!

posted @ 2018-10-11 22:16  晴和  阅读(1020)  评论(1编辑  收藏  举报