花兩分鐘靜心看看,望您有所收穫
1224:最大子矩陣
時間限制: 1000 ms 記憶體限制: 65536 kb
提交數: 3073 通過數: 1958
已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空(大小至少是1×11×1)子矩陣。
比如,如下\(4×4\)的矩陣
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
的最大子矩陣是
9 2-4 1
-1 8
這個子矩陣的大小是1515。
輸入是乙個n×nn×n的矩陣。輸入的第一行給出n(0輸出最大子矩陣的大小。
40 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
我的做法就是暴力列舉,兩層迴圈列舉矩陣左上角的座標,再兩層迴圈列舉右下角座標,然後求值。
ans 就是所有值中取個max。
在求矩陣和時,我們不用乙個點乙個點的累加,而是可以預先求出每一行的值,一行一行地累加。
這就用到了字首和。用qian[h][i]記錄第h行,從第乙個元素到第i個元素的和,這樣用qian[h][m] - qian[h][n - 1]就能得到第\(h\)行從第\(n\)列到第\(m\)列的值了。
由於乙個點可能是負的,所以ans要初始為負無窮
#define f(i,a,b) for(int i=a;i<=b;i++)
#define uf(i,a,b) for(int i=a;i>=b;i--)
#define inf 0x3fffffff
using namespace std;
const int n = 110;
int n, g[n][n];//g存大矩陣
int a, b, x, y;
int qian[n][n];//字首和優化
int ans = -inf;//ans初始為負無窮
int val(int a, int b, int x, int y)
return res;
}int main()
//得到字首和
f(h,1,n)
} //列舉左上點和右下點
f(a,1,n)
}} }
//輸出
cout << ans;
return 0;
}
題解 新技巧 一本通1282 最大子矩陣
題目傳送 雖然已知是dp,但第一眼看挺矇的,想了想後設了個a i j k l 表示長 座標 為i j,寬 座標 為k l的矩陣,但根本找不到狀態轉移方程啊。後借鑑題解 後領悟到的另一種方法 任何問題都有它的簡化,看到二維,沒辦法時我們可以考慮一下一維 求一維陣列的乙個最大連續段,我們可以設b i 為...
資訊學奧賽一本通C 語言 1224 最大子矩陣
題目描述 已知矩陣的大小定義為矩陣中所有元素的和。給定乙個矩陣,你的任務是找到最大的非空 大小至少是1 1 子矩陣。比如,如下4 4的矩陣 09 4 1 2218 7 6 40021 2 的最大子矩陣是 9 4 1218 這個子矩陣的大小是15。輸入 輸入是乙個n n的矩陣。輸入的第一行給出n 0 ...
關於一本通矩陣乘法
矩陣相乘最重要的方法是一般矩陣乘積。它只有在第乙個矩陣的列數 column 和第二個矩陣的行數 row 相同時才有意義 1 一般單指矩陣乘積時,指的便是一般矩陣乘積。乙個m n的矩陣就是m n個數排成m行n列的乙個數陣。由於它把許多資料緊湊地集中到了一起,所以有時候可以簡便地表示一些複雜的模型,如電...