给定一个矩阵,求和最大的子矩阵

题目:输入n,代表方形矩阵的维度,然后输入n^2个整数。请输出和最大的子矩阵的和。
要点:利用了最大连续子串和的思路,实际上也是动态规划的题目。这里再强调一下,对于动态规划的题目,我们经常会使用到-1下标,这样会使得编程很方便。如何能够正常的使用-1下标呢?见代码:

#include <iostream>
using namespace std;
int mat[100][100];
int s[101][101];
int n;
int x[101];
int *dp;
int(*sum)[101];
void getSum(int a[], int i, int j){//从第j行开始,维度为i
    for (int k = 0; k < n; k++)
    {
        a[k] = sum[j + i - 1][k] - sum[j - 1][k] - sum[j + i - 1][k - 1] + sum[j - 1][k - 1];
    }
}
inline int max(int a, int b)
{
    return a>b ? a : b;
}
int main(){
    sum = reinterpret_cast<int(*)[101]>(&s[1][1]);//这样就可以使用sum[-1][-1]
    cin >> n;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            cin >> mat[i][j]; 
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            sum[i][j] = sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1] + mat[i][j];
        }
    }//sum[i][j]保存的是mat[0][0] 和 mat[i][j]之间组成的矩阵的和

    int ret = 0;
    dp = reinterpret_cast<int*>(x + 1);//这样就可以用dp[-1]
    for (int i = 1; i <= n;i++)//最大子矩阵行的维度为i
    {
        for (int j = 0; j + i <= n; j++)//最大子矩阵从第j行开始
        {
            int arr[100];
            getSum(arr, i, j);
            int temp = 0;
            for (int k = 0; k < n; k++){
                dp[k] = max(dp[k - 1], temp + arr[k]);
                if (ret < dp[k])
                {
                    ret = dp[k];
                }
                temp += arr[k];
                if (temp < 0)
                {
                    temp = 0;
                }
            }
        }
    }
    return 0;
}
点赞