最大子矩阵和问题=。=
最朴素的方式是枚举矩阵左上角的点和右下角的点,然后计算和,复杂度是n^4
这里可以利用动态规划来进行优化
枚举子矩阵的起始行i和终止行j,然后将其求和使其转化为一维的数组,然后利用动态规划在O(n)的复杂度内求出最大和即可。复杂度是n^3对于n<=100的时候足够了
#include <cstdio> #include <climits> #include <algorithm> #include <cstring> using namespace std; const int maxn = 105; const int INF = INT_MAX / 2; int sum[maxn][maxn],v[maxn][maxn],t[maxn]; int maxsum(int *f,int n) { int ans = -INF,now = -INF; for(int i = 1;i <= n;i++) { now = max(now + f[i],f[i]); ans = max(ans,now); } return ans; } int main() { int n; while(~scanf("%d",&n)) { int ans = -INF; for(int i = 1;i <= n;i++) { for(int j = 1;j <= n;j++) { scanf("%d",&v[i][j]); sum[i][j] = sum[i - 1][j] + v[i][j]; } } for(int j = 1;j <= n;j++) { for(int k = j + 1;k <= n;k++) { for(int i = 1;i <= n;i++) { t[i] = sum[k][i] - sum[j - 1][i]; } ans = max(ans,maxsum(t,n)); } } printf("%d ",ans); } return 0; }