• 试题 历届试题 最大子阵(dp)


    问题描述
      给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。

      其中,A的子矩阵指在A中行和列均连续的一块。
    输入格式
      输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
      接下来n行,每行m个整数,表示矩阵A。
    输出格式
      输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
    样例输入
    3 3
    -1 -4 3
    3 4 -1
    -5 -2 8
    样例输出
    10
    样例说明
      取最后一列,和为10。
    dp经典题,枚举行与行之间列的叠加,形成一维数组,转化为一维数组最大子段和,dp[i]=max(dp[i-1]+a[i],a[i]);
    代码如下
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e4;
    const int inf=0x3f3f3f;
    int dp1[maxn];
    int dp2[maxn];
    int a[maxn][maxn];
    int sum=-inf;
    int main(){
        int n,m;cin>>n>>m;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                    cin>>a[i][j];
        for(int i=1;i<=n;i++){
            memset(dp1,0,sizeof(dp1));///把i项行、i+i+1行的列、i+(i+1)....n的列合一起,变成一行,转为一维数组解决最大子段和
            for(int j=i;j<=n;j++){
                for(int k=1;k<=m;k++){
                    dp1[k]+=a[j][k];
                }
            memset(dp2,0,sizeof(dp2));///开一个数组找一行里的最大子段和
                for(int u=1;u<=m;u++){
                    dp2[u]=max(dp2[u-1]+dp1[u],dp1[u]);
                    if(dp2[u]>sum)sum=dp2[u];///找到大的更新
                }
            }
        }
        cout<<sum<<endl;
        return 0;
    }
  • 相关阅读:
    二分查找 && 三分查找
    LeetCode || 大杂烩w
    LeetCode || 递归 / 回溯
    LeetCode || 双指针 / 单调栈
    HITICS || 2018大作业 程序人生 Hello's P2P
    思维 || Make It Equal
    国庆集训 || Wannafly Day4
    国庆集训 || Wannafly Day1
    区间DP || HDU 6249 Alice’s Stamps
    10进制转k进制
  • 原文地址:https://www.cnblogs.com/mohari/p/12979787.html
Copyright © 2020-2023  润新知