zoukankan      html  css  js  c++  java
  • 最大子矩阵和问题

    题目描述

    最大子矩阵和问题。
    给定m行n列的整数矩阵A,求矩阵A的一个子矩阵,使其元素之和最大。

    输入格式:
    第一行输入矩阵行数m和列数n(1≤m≤100,1≤n≤100),再依次输入m×n个整数。

    输出格式:
    输出第一行为最大子矩阵各元素之和,第二行为子矩阵在整个矩阵中行序号范围与列序号范围。

    输入样例1:

    5 6
    60 3 -65 -92 32 -70
    -41 14 -38 54 2 29
    69 88 54 -77 -46 -49
    97 -32 44 29 60 64
    49 -48 -96 59 -52 25
    

    输出样例1:
    输出第一行321表示子矩阵各元素之和,输出第二行2 4 1 6表示子矩阵的行序号从2到4,列序号从1到6

    321
    2 4 1 6
    

    解题思路

    这道题我们可以与最大子字段和结合起来。使用动态规划完成。

    我们可以把矩阵的多行合并成一行,然后按照求取最大子字段和的方式求得合并后的最大子字段。其值就是最大子矩阵的值

    根据子字段的起始和结束位置,以及我们合并的行的信息,便能够得出最大子矩阵的详细信息。

    代码如下:

    #include<bits/stdc++.h>
    using namespace std;
    int matrix[100][100];
    /**
     * 从第一行开始,逐渐将1行、2行、3行当做一行得出最大值
     * 
     * 找出最大子字段和即可
     */
    int main(){
        int m,n;
        scanf("%d %d",&m,&n);
        int startRow,endRow,startCol,endCol;
    
        for(int i=0;i<m;++i){
            for(int j=0;j<n;++j){
                scanf("%d",&matrix[i][j]);
                getchar();
            }
        }
    
        //记录多行合并成一行时的值
        int *col = new int[n];
        int max=0;
    
        for(int i=0;i<m;++i){//从第i行开始
            for(int j=0;j<n;j++){//每换起始行,就清空一次col
                col[j]=0;
            }
            for(int j=i;j<m;++j){//合并到第j行,j只能在i下面
                for(int k=0;k<n;++k){
                    col[k]+=matrix[j][k];//从i行合并到j行,每一列的值
                }
                //求最大子字段和
                int *dp = new int[n];
                int *start = new int[n];//记录子字段的起始位置
                memset(start,0,sizeof(int)*n);
                dp[0]=col[0];
                for(int p=1;p<n;p++){
                    if(dp[p-1]>0) {
                            dp[p] = dp[p-1]+col[p];
                            start[p]=start[p-1];//与前一个相加,起始位置不变
                        }
                    else{ 
                        dp[p]=col[p];
                        start[p]=p;//从当前位置重新累加,以当前位置为起始点
                    }
                }
                
                for(int p=0;p<n;++p){
                    if(dp[p]>max) {
                        max = dp[p];
                        startRow=i;
                        endRow=j;
                        startCol=start[p];
                        endCol=p;
                    }
                }
                delete[] dp;
                delete[] start;
                }
            }
    
        printf("%d
    ",max);
        printf("%d %d %d %d",startRow+1,endRow+1,startCol+1,endCol+1);
    
    
        return 0;
    }
    
    
  • 相关阅读:
    MySQL数据类型
    MySQL体系结构
    数据库MySQL——安装
    MySQL安装-windows安装
    vc++木马源码免杀一些常用方法
    222
    11
    metasploit(MSF)渗透平台命令大全
    Oracle数据库提权(dba权限执行系统命令)
    Python之random模块和time模块
  • 原文地址:https://www.cnblogs.com/ylcc-zyq/p/12560333.html
Copyright © 2011-2022 走看看