日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【POJ - 3494】Largest Submatrix of All 1’s(加一点思维后化成 单调栈)

發布時間:2023/12/10 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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 0

Sample 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(加一点思维后化成 单调栈)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。