zoukankan      html  css  js  c++  java
  • P1169 [ZJOI2007]棋盘制作

    随手一写就冲进了最优解的第一页?

    本来以为是dp, 但是经过仔细分析...这不就是二进制 + 单调栈么?

    然后想正方形的情况...emm..好像正方形一定是最大矩形的子矩阵吧!

    听说此题dp也可行?

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <stack>
    using namespace std;
    typedef pair<int, int> P;
    const int MAXN = 2e3 + 20;
    const int INF = 0x3f3f3f3f;
    inline int read()
    {
        int x = 0; char ch = getchar();
        while(!isdigit(ch)) ch = getchar();
        while(isdigit(ch)) x = x * 10 + ch - '0', ch = getchar();
        return x;
    }
    
    int N, M;
    int sum[2][MAXN];
    bool map[2][MAXN];
    P ans(1, 1);
    
    struct Sta
    {
        stack<P> sta;
        
        void init(){
            pushin(0);
            while(!sta.empty()) sta.pop();
            return ;
        }
    
        void pushin(int h){
            if(sta.empty() || sta.top().first < h) {
                sta.push(P(h, 1));
                return ;
            }
            int len = 0, hei = INF;
            while(!sta.empty() && sta.top().first > h) {
                P p = sta.top(); sta.pop();
                len += p.second; hei = min(hei, p.first);
                
                ans.first = max(ans.first, len * p.first);
                ans.second = max(ans.second, min(len, hei) * min(len, hei));
            }
            sta.push(P(h, len + 1));
            return;
        }
    }S;
    
    int main()
    {
        cin>>N>>M; int d = 0;
        
        for(int i = 1; i <= N; i++){
            d ^= 1;
            
            if(i == 1) {
                for(int j = 1; j <= M; j++) 
                    sum[d][j] = 1, map[d][j] = read();
                continue;
            }
            for(int j = 1; j <= M; j++){
                map[d][j] = read();
                sum[d][j] = (map[d ^ 1][j] ^ map[d][j]) ? sum[d ^ 1][j] + 1 : 1;
                if(j - 1 && map[d][j] ^ map[d][j - 1]) S.pushin(sum[d][j]);
                else S.init(), S.pushin(sum[d][j]);
            }
            S.init();        
        }
        cout<<ans.second<<endl;
        cout<<ans.first<<endl;
        return 0;
    }

     

     

  • 相关阅读:
    vim 高级使用技巧第二篇
    你所不知道的Html5那些事(一)
    linux设备驱动第三篇:如何实现一个简单的字符设备驱动
    Android Metro风格的Launcher开发系列第二篇
    「BZOJ3123」[SDOI2013]森林
    【模板】左偏树
    「luogu3157」[CQOI2011]动态逆序对
    「luogu3567」[POI2014]KUR-Couriers
    【模板】二逼平衡树
    「luogu3313」[SDOI2014]旅行
  • 原文地址:https://www.cnblogs.com/wsmrxc/p/9309700.html
Copyright © 2011-2022 走看看