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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m))

發布時間:2024/4/19 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m)) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前置問題:51nod 1102 面積最大的矩形

附上鏈接:
51nod 1102 面積最大的矩形
這題的題解博客

需要了解的知識:單調棧,在前置問題中已經講解。

解題思路

  • 對每行求左邊連續1的個數,得到數組a[i][j];
  • 對于第j列,找出每個位置i的數字a[i][j]上面第一個比它小數字l,和下面第一個比它小的數字r。
  • 由這個點所在列為底,這個點的數字為最小值產生的矩形的面積為a[i][j]*(r-l-1),用這一列每一個面積更新ans。
  • 上面2的求法就是單調棧了,總時間復雜度o(n*m)。
  • 代碼:

    #include <bits/stdc++.h> using namespace std; typedef long long ll; int a[510][510]; int l[510],r[510]; int main(){ios::sync_with_stdio(false);int m,n;cin >> m >> n;for(int i = 1;i <= m; ++i){for(int j = 1;j <= n; ++j){cin >> a[i][j];if(a[i][j] == 1) a[i][j] += a[i][j-1];}}int ans = 0;for(int i = 1;i <= n; ++i){memset(l,0,sizeof(l));memset(r,0,sizeof(r));stack<int> s; s.push(1);a[0][i] = a[m+1][i] = -1;for(int j = 2;j <= m+1; ++j){while(s.size() and a[j][i] < a[s.top()][i]){r[s.top()] = j;s.pop();}s.push(j);}while(s.size()) s.pop();s.push(m);for(int j = m-1;j >= 0; --j){while(s.size() and a[j][i] < a[s.top()][i]){l[s.top()] = j;s.pop();}s.push(j);}for(int j = 1;j <= m; ++j){ans = max(ans, (r[j]-l[j]-1)*a[j][i]);}}cout << ans << endl;return 0; }

    總結

    以上是生活随笔為你收集整理的51nod 1158 全是1的最大子矩阵(单调栈 ,o(n*m))的全部內容,希望文章能夠幫你解決所遇到的問題。

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