• 最大子矩阵,最大连续子数组进阶,动态规划初级,poj1050


    题目描述:现给出一个N*N矩阵,要求求出拥有最大和的子矩阵的和。

    例如:

    这样的一个矩阵,最大子矩阵的和为15;

    此题可以让人联想到求最大连续子数组,求最大子数组在上一篇文章中http://www.cnblogs.com/tz346125264/p/7560708.html。

    分析:最大子矩阵可以看为求最大连续子数组拓展到二维数组上,因为矩阵的性质同样在横向竖向上需要连续,那么可以想办法将这个二维数组简化为求连续子数组。

    思考:

    1.要求最大子矩阵,必须保证每个矩阵都被浏览到,为了保证运行时间尽可能不要重复浏览同一矩阵,故需制定规则,规则定为用i表示起始行,j表示终止行,j>=i,再使用k对列进行遍历,即可覆盖所有矩阵。

    2.进行化简成求连续子数组操作,以上为例,设i=2,j=4那么这个矩阵是这样,那么化为连续子数组即为4(9-4-1),11(2+1+8),-10(-6-4+0),1(2+1-2)

    求这个连续数组的最大连续子数组和便是这个矩阵(以i=2作为起始行,j=4作为终止行)的最大子矩阵,如此,整个矩阵的最大子矩阵便是这些最大子矩阵中的最大值。

    上代码:

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    int main(){
        int n;
        int a[101][101];
        int temp[101];
        cin>>n;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                cin>>a[i][j];
                /*
                为什么要进行相加?
                在化简为求连续最大子数组时,需要将i到j行的数进行相加sum(i,j),而这个sum{i,j}可有sum{0,j}-sum{0,i}得到
                为此提前做出相加方便之后化简 
                */
                a[i][j]+=a[i-1][j];
            }
        }
        int max = -10000;
        for(int i=1;i<=n;i++){
            for(int j=i+1;j<=n;j++){
                memset(temp,0,sizeof(temp));
                //求最大连续子数组操作 
                for(int k=1;k<=n;k++){
                    if(temp[k-1]>=0){
                        temp[k]=temp[k-1]+a[j][k]-a[i][k];
                    }else{
                        temp[k]=a[j][k]-a[i][k];
                    }
                    if(temp[k]>max){
                        max = temp[k];
                    }
                }
            }
        }
        cout<<max<<endl;
        return 0;
    } 
  • 相关阅读:
    spring:事务的5大隔离级别,7大传播行为
    spring事务管理(xml配置)与spring自带连接数据库JdbcTemplate
    spring顾问包装通知
    Spring常见的两种增强方式
    Spring-增强方式注解实现方式
    Spring----aop(面向切面编程)
    Spring_IOC
    服务器项目代码在本地打断点调试
    FreeMarker标签出错问题
    Eclipse启动项目没加载到webapps目录下
  • 原文地址:https://www.cnblogs.com/tz346125264/p/7568335.html
Copyright © 2020-2023  润新知