试题 历届试题 最大子阵(dp)
Posted mohari
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了试题 历届试题 最大子阵(dp)相关的知识,希望对你有一定的参考价值。
问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。
其中,A的子矩阵指在A中行和列均连续的一块。
输入格式
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。
接下来n行,每行m个整数,表示矩阵A。
输出格式
输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
-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; }
以上是关于试题 历届试题 最大子阵(dp)的主要内容,如果未能解决你的问题,请参考以下文章
[Hdp] lc面试题 17.24. 最大子矩阵(前缀和+列压缩+最大子阵和+面试常考)