思路
记录这道题主要是为了记录二位前缀和的做题思路,毕竟CSP都遇见现题了,当时还只过了8个点…
其实前缀和也是一种形式的dp,这里借用LeetCode-304官方题解的图片,它画得很清晰了
我们设dp[i][j]表示从矩阵左上角(0,0)到当前位置(i,j)的所有值之和,则不难得出图中的转移方程。减去dp[i-1][j-1]的原因是它在计算dp[i][j-1]+dp[i-1][j]中被计算了两次,要减掉多余的那一次。
这种思路在LeetCode周赛#225的T3中也有体现。
当我们对所有的(i,j)都算出前缀和后,用四重循环去依次枚举每一对左上角与右下角就行了。虽然纸面复杂度有O(n²* m²),但每一个右下角一定在左下角后面,所以对右下角的枚举并没有严格的平方级复杂度,所以还是能把题混过去的。
代码
int sum[110][110]; class Solution { public: int maxSumSubmatrix(vector<vector<int>>& mat, int k) { int m = mat.size(), n = mat[0].size(); for(int i = 1; i <= m; i++){ for(int j = 1; j <= n; j++){ sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + mat[i - 1][j - 1]; } } int ans = INT_MIN; for(int i = 1; i <= m; i++){ for(int j = 1; j <= n; j++){ for(int p = i; p <= m; p++){ for(int q = j; q <= n; q++){ int cur = sum[p][q] - sum[i - 1][q] - sum[p][j - 1] + sum[i - 1][j - 1]; if(cur <= k){ ans = max(ans,cur); } } } } } return ans; } };
评论
还没有任何评论,你来说两句吧!