To the Max
求最大子矩阵(和最大的矩阵)
输入样例
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
输出样例
15
思路
对于一维数组,用dp求最长公共子序列,dp[k]=max(dp[k-1]+a[k],a[k])
二维则是对行数遍历,对于第i行到第j行,求每一列的和,然后得到一个一维数组,求其最长公共子序列,所得最大值即为第i行到第j行中的最大子矩阵
代码
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
int a[105][105],summ[105][105],b[105],dp[105],anss,anss2;
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
cin>>a[i][j];
}
}
memset(summ,0,sizeof(summ));
for(int j=0;j<n;j++){
summ[0][j]=a[0][j];
for(int i=1;i<n;i++){
summ[i][j]=summ[i-1][j]+a[i][j];
}
}
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
for(int k=0;k<n;k++){
b[k]=summ[j][k]-summ[i][k]+a[i][k];
}
memset(dp,0,sizeof(dp));
dp[0]=b[0];
anss2=dp[0];
for(int k=1;k<n;k++){
dp[k]=max(dp[k-1]+b[k],b[k]);
if(dp[k]>anss2){
anss2=dp[k];
}
}
if(i==0&&j==0){
anss=anss2;
}
else{
anss=max(anss,anss2);
}
}
}
cout<<anss<<endl;
return 0;
}