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;
    }


  • 相关阅读:
    20080619 SQL SERVER 输入 NULL 的快捷键
    20090406 Adobe的“此产品的许可已停止工作”错误的解决办法
    20080908 Office Powerpoint 2007 不能输入中文的解决办法
    20080831 ClearGertrude Blog Skin 's cnblogs_code class
    20080603 Facebook 平台正式开放
    20080519 安装 Microsoft SQL Server 2000 时提示 创建挂起的文件操作
    test
    Linux—fork函数学习笔记
    SOA的设计理念
    Why BCP connects to SQL Server instance which start with account of Network Service fail?
  • 原文地址:https://www.cnblogs.com/Tovi/p/6194781.html
Copyright © 2011-2022 走看看