zoukankan      html  css  js  c++  java
  • [每日一题]:最大子矩阵和

    题目:

    一个M*N的矩阵,找到此矩阵的一个子矩阵,并且这个子矩阵的元素的和是最大的,输出这个最大的值。
    
    例如:3*3的矩阵:
    
    -1 3 -1
    2 -1 3
    -3 1 2
    
    和最大的子矩阵是:
    
    3 -1
    -1 3
    1 2
    

    题目链接:

    https://www.51nod.com/Challenge/Problem.html#problemId=1051

    最大子段和:

    建议不了解我的先戳一下

    侃侃:

    这个题是 最大子段和的 二维升级版,如何将二维的降为一维的呢?
    想一下,如果我们将 所有的一行压缩成一行,那么是不是就是我们
    求的最大子段和了。
    

    分析:

    预处理行和列,进行压缩,得到每一列的前缀和。
    枚举行。
    接下来跟求最大子段和类似,进行求即可。
    

    Code:

    #include <cstdio>
    #include <string>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    #define INF 0x3f3f3f3f
    
    using namespace std;
    
    typedef long long LL;
    
    const int maxn = 505;
    
    LL dp[maxn][maxn];
    
    LL a[maxn];
    
    int n,m;
    
    LL value;
    
    int main(void) {
    	scanf("%d%d",&m,&n);
    	for(int i = 1; i <= n; i ++) {
    		for(int j = 1; j <= m; j ++) {
    			scanf("%lld",&value);
    			// 预处理,进行压缩 
    			dp[i][j] = dp[i - 1][j] + value;
    		}
    	}
    	
    	LL ans = -INF;
    	
    	for(int i = 1; i <= n; i ++) {
    		for(int j = i; j <= n; j ++) {
    			LL num = 0;
    			// 我们将几行压缩成了一行,就成了求最大子段和 
    			for(int k = 1; k <= m; k ++) {
    				num += dp[j][k] - dp[i - 1][k];
    				if(num < 0) num = 0;
    				if(num > ans) ans = num;
    			}
    		}
    	}
    	cout << ans << endl;
    	return 0;
    }
    
  • 相关阅读:
    Swift,数组
    Android-Binder(一)
    Android 前台服务
    Android-Service和Thread
    Android-认识Service
    Android-属性动画
    Android-Activity的切换效果
    Android-LayoutAnimation
    django模板解析 循环列表中 切片和求长度
    ubuntu16 安装cron 以及使用
  • 原文地址:https://www.cnblogs.com/prjruckyone/p/12828121.html
Copyright © 2011-2022 走看看