【POJ - 3494】Largest Submatrix of All 1’s(加一点思维后化成 单调栈)
題干:
Given a?m-by-n?(0,1)-matrix, of all its submatrices of all 1’s which is the largest? By?largest?we mean that the submatrix has the most elements.
Input
The input contains multiple test cases. Each test case begins with?m?and?n?(1 ≤?m,?n?≤ 2000) on line. Then come the elements of a (0,1)-matrix in row-major order on?m?lines each with?n?numbers. The input ends once EOF is met.
Output
For each test case, output one line containing the number of elements of the largest submatrix of all 1’s. If the given matrix is of all 0’s, output 0.
Sample Input
2 2 0 0 0 0 4 4 0 0 0 0 0 1 1 0 0 1 1 0 0 0 0 0Sample Output
0 4題目大意:
? ? ? ? 求最大的子矩陣中數的和(其實也就是1的個數)
解題報告:
大佬說: ? 想起在學習dp時,曾經遇到過矩形求最大n子段和問題,用的狀態壓縮,這里也可以用這個,把矩形壓縮成一條線,然后的過程,就是例題求矩形面積了,不過這里要求n遍,因為每行都要壓縮,每行都要求一遍。于是這個題變得就簡單多了。不過要注意的是最后需要枚舉每一行的狀態,而不能枚舉maze值最大那一行的狀態,(即:就算這一行的某一列是把這一列本該有的那個高度攔腰折斷,也要枚舉這一行)因為說不定在別的列的值大呢,而且,就算攔腰折斷了,這也算是一種狀態啊,所包含的所有狀態必須全部枚舉一遍,不重不漏,才能保證最終結果的正確性。
AC代碼:
#include<iostream> #include<cmath> #include<cstdio> #include<algorithm> #include<stack>using namespace std; const int MAX = 2000 + 5; int n,m; int maze[MAX][MAX]; int L[MAX],R[MAX];void getl(int i) {stack<int > sk;//要找他左側的第一個嚴格比他小的元素 所以需要從左向右維護一個嚴格單調遞增棧 for(int j = 1; j<=n; j++) {while(!sk.empty() && maze[i][sk.top() ]>=maze[i][j] ) sk.pop();if(sk.empty() ) L[j] = 0;else L[j] = sk.top();sk.push(j);}} void getr(int i) {stack<int > sk;//要找他右側的第一個嚴格比他小的元素 所以需要從右向左維護一個嚴格單調遞增棧 for(int j = n; j>=1; j--) {while(!sk.empty() && maze[i][sk.top() ]>=maze[i][j] ) sk.pop();if(sk.empty() ) R[j] = n+1;else R[j] = sk.top();sk.push(j);}} void init() {for(int i = 1; i<=m; i++)for(int j = 1; j<=n; j++)maze[i][j]=0; } int main() {while(~scanf("%d %d",&m,&n) ) {//m行n列 init();for(int i = 1; i<=m; i++) {for(int j = 1; j<=n; j++) {int tmp;scanf("%d",&tmp);if(tmp==1) {maze[i][j]=maze[i-1][j]+1;}}}//至此我們已經有了截止第i行的(1~i)每一個j的連續高度, int maxx=-1;for(int i = 1; i<=m; i++) {getl(i);getr(i);//加入實時判斷,這樣就不用開二維的L[][]和R[][]了!! // printf("i=%d 時 ",i); for(int j = 1; j<=n; j++) { // printf("L[%d] =%d ",j,L[j]);maxx= max(maxx, maze[i][j] * (R[j] - L[j] -1) );} // printf("\n");}printf("%d\n",maxx);}return 0 ;}總結: ?
? ?1.實時判斷!這樣就不用開一個二維數組了!最近很多題都用到了for循環中實時判斷實時操作的題!以后有空來一波總結。
? ?2. 適量的注釋有的時候真的讓人看著神清氣爽
總結
以上是生活随笔為你收集整理的【POJ - 3494】Largest Submatrix of All 1’s(加一点思维后化成 单调栈)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: schost.exe - schost是
- 下一篇: SchSvr.exe - SchSvr是