zoukankan      html  css  js  c++  java
  • 听课笔记--DP--最大子矩阵和


    最大子矩阵问题

    给定一个n*n(0<n<=120)的矩阵,

    矩阵内元素有正有负,

    请找到此矩阵的内部元素和最大的子矩阵

    样例输入:

    4

    0 -2 -7  0

    9  2 -6  2

    -4  1 -4  1

    -1  8  0 -2

    样例输出:

    15


    • 方法一:

      用二维前缀和维护然后一个个点遍历;

      时间复杂度:O(N4);

    • 方法二:

      DP

      先请明白这道题:

      最大子段和

      嗯?这不是一维的吗。和这道题有什么关系?

      请看这张图:

         这样就不难看出,我们只要枚举区间的左端点l和右端点r;
         
         同时用维护的二维前缀和求出每一段1,2,3,4,的值
         
         然后竖着来一遍最大字段和(O(N))就好了
         
         
         时间复杂度:O(N3)
      

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=150;
    int a[maxn][maxn];
    int sum[maxn][maxn];
    int line[maxn],c[maxn];
    int l,r;
    int n;
    int solve()
    {
    	int minx=min(0,line[1]),maxx=line[1];//
    	for(int i=2;i<=n;i++)
    	{
    		maxx=max(maxx,c[i]-minx);
    		minx=min(minx,c[i]);
    	}
    	return maxx;
    }
    int main()
    {
    	int ans=-99999;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=1;j<=n;j++)
    		{
    		cin>>a[i][j];
    		sum[i][j]=sum[i][j-1]+a[i][j];
    	    }
    	}
    	for(r=1;r<=n;r++)
    	{
    		for(l=1;l<=r;l++)
    		{
    			for(int i=1;i<=n;i++)
    			{
    			line[i]=sum[i][r]-sum[i][l]+a[i][l];
    			c[i]=c[i-1]+line[i];	
    		    }
    		     ans=max(solve(),ans);
    		     memset(c,0,sizeof(c));
    		     memset(line,0,sizeof(line)); 
    		}
    	
    		
    	}
    	cout<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    MapXtreme中鹰眼图与本地地图联动
    MapXtreme删除图层中某个对象
    winform textbox屏蔽中文输入法
    爬虫日记之美味汤的各种属性值的运用
    爬虫日记之robots协议
    爬虫日记之图片爬取和ip查询
    爬虫日记之关键字搜索引擎爬取
    爬虫之修改请求头
    爬虫第一步,re模块来铺路
    三个数据分析的模块
  • 原文地址:https://www.cnblogs.com/Rye-Catcher/p/8478839.html
Copyright © 2011-2022 走看看