信息学奥赛一本通(1224:最大子矩阵)
1224:最大子矩陣
時間限制: 1000 ms ??? ??? 內存限制: 65536 KB
提交數: 5292 ??? 通過數: 3128
【題目描述】
已知矩陣的大小定義為矩陣中所有元素的和。給定一個矩陣,你的任務是找到最大的非空(大小至少是1×1)子矩陣。
【輸入】
輸入是一個N×N的矩陣。輸入的第一行給出N(0
【輸出】
輸出最大子矩陣的大小。
【輸入樣例】
40 -2 -7 09 2 -6 2 -4 1 -4 1 -1 8 0 -2【輸出樣例】
15【分析】
? ? ? ? 這道題的解法有前綴法和動態規劃法,貪心算法解法暫時還沒有想到,下面來講解一下前綴法。
? ? ? ? 前綴和是一個數組的某項下標之前(包括此項元素)的所有數組元素的和。設a為原數組,b為前綴和數組。
? ? ? ? 一維數組前綴和定義為:,二維數組前綴和定義為:,以樣例為例,原矩陣a為:
0 -2?-7?0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
則,前綴和矩陣b為:
0 -2?-9 -9
9 9 -4 -2
5 6 -11 -8
4 13 -4 -3
? ? ? ? 遞推公式為:b[x][y]=b[x-1][y]+b[x][y-1]-b[x-1][y-1]+a[i][j]。這個遞推公式也不難理解,就是容斥原理。比如,上面b數組的第4行第2列數據13,套用上述公式,其值就是:13 = 6?+ 4?- 5?+ 8。
? ? ? ? 回到本題,假設求下列原矩陣紅框部分子矩陣的和,肉眼可見,下圖子矩陣和 = -7。
? ? ? ? 用前綴和矩陣求解方式為:-11?- (-9)- 5 + (-4)?= -7。
? ? ? ? 這里給出O(n^4)的代碼,O(n^3)的解法參見后續的1282題目。
? ? ? ? 四重循環,設子矩陣左上角坐標為(k,l),右下角(i,j)。則分別枚舉 i,j,k,l 即可,枚舉范圍 i∈[1,n],j∈[1,n],k∈[1,i ],l∈[1,j ]。
【參考代碼】
#include <stdio.h> #define N 110 int a[N][N]; int sums[N][N]; int main() {int i,j,k,l,n,t,max;scanf("%d",&n);for(i=1;i<=n;i++) //前綴和 {for(j=1;j<=n;j++){scanf("%d",&a[i][j]);sums[i][j]=sums[i-1][j]+sums[i][j-1]-sums[i-1][j-1]+a[i][j];}}max=sums[1][1];for(i=1;i<=n;i++){for(j=1;j<=n;j++){for(k=1;k<=i;k++) //枚舉每個子矩陣,左上角(k,1),右下角(i,j),子矩陣和 {for(l=1;l<=j;l++){t=sums[i][j]-sums[i][l-1]-sums[k-1][j]+sums[k-1][l-1];if(t>max)max=t;}}}}printf("%d\n",max);return 0; }http://ybt.ssoier.cn:8088/problem_show.php?pid=1224
總結
以上是生活随笔為你收集整理的信息学奥赛一本通(1224:最大子矩阵)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenJudge NOI 1.5 16
- 下一篇: 信息学奥赛一本通 1091:求阶乘的和