zoukankan      html  css  js  c++  java
  • NYoj_104最大和

    最大和

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:5
    描述

    给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最大,并把这个子矩阵称为最大子矩阵。 
    例子:
    0 -2 -7 0 
    9 2 -6 2 
    -4 1 -4 1 
    -1 8 0 -2 
    其最大子矩阵为:

    9 2 
    -4 1 
    -1 8 
    其元素总和为15。 

    输入
    第一行输入一个整数n(0<n<=100),表示有n组测试数据;
    每组测试数据:
    第一行有两个的整数r,c(0<r,c<=100),r、c分别代表矩阵的行和列;
    随后有r行,每行有c个整数;
    输出
    输出矩阵的最大子矩阵的元素之和。
    样例输入
    1
    4 4
    0 -2 -7 0 
    9 2 -6 2 
    -4 1 -4 1 
    -1 8 0 -2 
    
    样例输出

    15

    算法分析:二维数组求最大和,本题可以转换成为一维。

    1. 将行划分,划分的结果为所有情况

    2.将划分好的“新行”进行合并成“一行”,

    3.对“一行”进行一维的求最大子段和

    举个例子:

    0  -2  -7  0

    9   2  -6  2

    -4  1  -4   7

    -1  8  0   -2

    我们分别用i j表示起始行和终止行,遍历所有的可能:

    for(i=1;i<=n;i++)

    for(j=i;j<=n;j++) {}

    我们考察其中一种情况 i=2 j=4,这样就相当与选中了2 3 4三行,求那几列的组合能获得最大值,由于总是 2 3 4行,所以我们可以将这3行”捆绑”起来,变为求 4(9-4-1),11(8+2+1),-10(-6-4+0),7(7+2-2)的最大子段和,ok,问题成功转化为一维的情况!

    注意:代码中还有一个地方需要注意,就是读入原始数据的时候,要处理一下,再保存到数组中,每一行的数据都不是原来的数据,而是加上同一列以上各行的数据,这样以来,在合并求和的时候就比较方便了。比如求2,3两行的和,只要第三行的值减去第一行的值就行了

    #include <iostream>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    
    int a[110][110], b[110];
    #define mem(a) memset(a, 0, sizeof(a))
    
    int Max_sum(int b[], int c) {
    	int sum = 0, res = -9999999;
    	for (int i = 1; i<=c; i++) {
    		if (sum > 0)	sum += b[i];
    		else	sum = b[i];
    		if (sum > res)	res = sum;
    	}
    	return res;
    }
    
    int main() {
    	int t;
    	scanf("%d",&t);
    	while (t --) {
    		mem(a);
    		mem(b);
    		int r, c;
    		scanf("%d%d",&r, &c);
    		for (int i = 1; i<=r; i++) {
    			for (int j = 1; j<=c; j++) {
    				scanf("%d",&a[i][j]);
    				a[i][j] += a[i-1][j];
    			}
    		}
    		int res = -9999999;
    		for (int i = 0; i<=r; i++) {
    			for (int j = i+1; j<=r; j++) {
    				for (int k = 1; k<=c; k++) {
    					b[k] = a[j][k] - a[i][k];
    				}
    				int Max = Max_sum(b, c);
    				if (res < Max)	res = Max;
    			}
    		}
    		printf("%d
    ",res);
    	}
    	return 0;
    }


  • 相关阅读:
    django with mysql (part-4)
    django with mysql (part-3)
    django with mysql (part-2)
    [LeetCode] 22. 括号生成(回溯/DP)
    [算法]求满足要求的进制(辗转相除(欧几里得算法),求最大公约数gcd)
    [算法]体积不小于V的情况下的最小价值(0-1背包)
    [LeetCode]96. 不同的二叉搜索树(DP,卡特兰数)
    [LeetCode]98. 验证二叉搜索树
    [LeetCode]21. 合并两个有序链表(递归)
    [LeetCode]538. 把二叉搜索树转换为累加树
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194781.html
Copyright © 2011-2022 走看看