20分钟就a了,突然感觉自己好强啊,嗯♂?
先是最基本的思路,枚举所有子矩阵,必定超时
计算所有子矩阵中的计算有大量重复,尝试定义状态dp[i][j],表示以i行j列元素为矩阵右下角的子矩阵所得到的最大子矩阵和
然而这样并不能转移
加一个限制,状态dp[i][j][k],i和j同上,k表示这个子矩阵高度为k,那么同一行的dp[i][j][k]就可以由dp[i][j-1][k]转移过来
突然发现,这种状态定义,这问题并不能不是最大子串
然后轻松加愉快的做出来
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int A[111][111];
int dp[111][111]; //dp[i][j][k]表示以第i行第j列的元素为子矩阵右下角得到的最小和,子矩阵高k
//i可省略
int main()
{
cin.sync_with_stdio(false);
int n;
for (int i=0;i<111;i++) //老生常谈初始化,忘了就gg
dp[0][i]=-99999999;
while (cin>>n)
{
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
cin>>A[i][j];
int result(INT_MIN);
for (int i=1;i<=n;i++)
for (int j=1;j<=n;j++)
{
int above(0); //above是A[i][j]和它上方k-1个元素之和,避免重复计算
for (int k=1;k<=i;k++)
{
above+=A[i-k+1][j];
dp[j][k]=max(dp[j-1][k]+above,above);
result=max(result,dp[j][k]);
}
}
cout<<result<<endl;
}
return 0;
}