poj1050-求二维数组子数组和的最大值
来源:互联网 发布:淘宝电脑改差评步骤 编辑:程序博客网 时间:2024/05/16 07:01
题意:给定一个二维数组,值有正有负,矩阵的规模不超过100*100,矩阵元素在-127到127之间,求该二维数组的一个子数组,使得该数组的元素之和在所有的子数组中是最大的。
解法一:
对整个矩阵进行枚举,采用四重循环,计算每个子矩阵的元素之和,在计算所有的子矩阵之和是有很多重复的计算,可以考虑用“空间换时间”的方法,先计算出以(1,1)为左上点,(i,j)为右下点所表示的矩阵元素之和为partSum[i,j].则以(x,y)为左上点(i,j)为右下点的矩阵元素之和为partSum[i,j] - partSum[i,y-1] - partSum[x-1,j] + parSum[x-1,y-1]
整个时间复杂度为O(m*n)+O(m*m*n*n) = O(m*m*n*n);
解法二:
将二维转化为一维处理,解法一中使用了4重循环,第1,2重是对行的枚举,第3,4重是对列的枚举,这里将1,2重对行的枚举保留,当上下行(i表示上行,j表示下行)确定时,对列的选择可以看作是求一维数组子数组的最大和,只不过该一维数组中每个元素是由某列中第i到j行元素之和组成的,求一维数组子数组和的最大值可以参考我前一篇博客。
整个时间复杂度为O(m*n*min(m,n))
#include <stdio.h>int A[110][110];int partSum[110][110];/*方法一:使用四重循环枚举一个个的比较*//*求得从左上角到(i,j)所表示的矩阵的各元素的和*/void CalculatePartSum(int m, int n){int i, j;/*初始化处理*/for (i = 0; i <= n; i++){partSum[0][i] = 0;}for (i = 0; i <= m; ++i){partSum[i][0] = 0;}/*求值*/for (i = 1; i <= m; ++i){for (j = 1; j <= n; ++j){partSum[i][j] = partSum[i - 1][j] + partSum[i][j - 1] - partSum[i - 1][j - 1] + A[i][j];}}}int MaxSumOne(int m, int n){int maximum = -200;int i, j;int x, y;int sum;CalculatePartSum(m, n);/*求最大值,需要4重循环*/for (i = 1; i <= m; ++i){for (j = i; j <= m; ++j){for (x = 1; x <= n; x++){for (y = x; y <= n; y++){sum = partSum[j][y] - partSum[j][x - 1] - partSum[i - 1][y] + partSum[i - 1][x - 1];if (sum > maximum)maximum = sum;}}}}return maximum;}/*方法二将二维转化为一维处理,当子矩阵的上下行确定时,把上下行中每一列的数据当作一个单元,确定左右列的过程就是求以列为单元的一维数组的子数组最大和的过程*/int MaxSumTwo(int m, int n){int i, j, k;int maximum = -1000;int start, all;int B[110];for (i = 1; i <= m; i++){for (k = 1; k <= n; k++){B[k] = 0;}for (j = i; j <= m; j++){for (k = 1; k <= n; k++){B[k] += A[j][k];}start = B[n];all = B[n];for (k = n - 1; k >= 1; k--){if (start < 0)start = 0;start += B[k];if (start > all)all = start;}if (all > maximum)maximum = all;}}return maximum;}int main(){int i, j, N;while (EOF != scanf("%d", &N)){for (i = 1; i <= N; ++i){for (j = 1; j <= N; j++){scanf("%d", &A[i][j]);}}printf("%d\n", MaxSumTwo(N, N));}return 0;}
我在poj 上进行了测试,解法一耗时63MS,解法二耗时16MS
0 0
- poj1050-求二维数组子数组和的最大值
- poj1050 动态规划 求二维数组中子矩阵和的最大值
- POJ1050二维数组的最大子数组和
- 求数组的子数组和最大值
- 求子数组和的最大值算法
- 求子数组和的最大值
- 求子数组之和的最大值(二维)
- poj1050 二维数组最大子序列矩阵和
- 二维子数组最大值
- 二维数组求最大值
- 二维数组求最大值
- 求子数组的最大值
- 求子数组的最大值
- 求数组子数组和最大值
- 求数组的子数组和的最大值
- 求数值型数组的子数组和最大值
- java如何求二维数组的和、最大值和最小值。
- 求数组的子数组之和最大值
- 一张图读懂余额宝
- Partition List
- 我的第三课:【JSON】====JSON 使用
- 视频参数(流媒体系统,封装格式,视频编码,音频编码,播放器)对比
- 公司年会中如何抽到特等奖?
- poj1050-求二维数组子数组和的最大值
- Symmetric Tree(中心对称树)
- vim默认显示行号
- nginx搭配codeigniter的配置(windows/linux)
- 黑马程序员_异常
- RMAN备份
- 搭建c/c++eclipse工具链
- 9.1常用的预编译
- 与其追求完美的O2O闭环模式,倒不如先把蛋糕做大!