zoukankan      html  css  js  c++  java
  • AcWing

    https://www.acwing.com/problem/content/154/

    悬线法dp,悬线dp,不知道这样对不对,反正能过,看看别人的证明:

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n, m;
    int g[1005][1005];
    int up[1005][1005];
    
    stack<int> st;
    stack<int> st2;
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        //freopen("citygame.in", "r", stdin);
        //freopen("citygame.out", "w", stdout);
        //int T;
        //scanf("%d", &T);
        int T = 1;
        while(T--) {
            scanf("%d%d", &n, &m);
            for(int i = 0; i <= n + 1; ++i) {
                memset(g[i], 0, sizeof(g[i][0]) * (m + 1));
                memset(up[i], 0, sizeof(up[i][0]) * (m + 1));
            }
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    char tmp[2];
                    scanf("%s", tmp);
                    g[i][j] = (tmp[0] == 'F');
                }
            }
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j)
                    up[i][j] = (g[i][j] == 0 ? 0 : up[i - 1][j] + 1);
            }
            int ans = 0;
            for(int i = 1; i <= n; ++i) {
                while(!st.empty()) {
                    st.pop();
                    st2.pop();
                }
                for(int j = 1; j <= m; ++j) {
                    int prej = j;
                    while(!st.empty() && up[i][st.top()] > up[i][j]) {
                        ans = max(ans, (j - st2.top()) * up[i][st.top()]);
                        st.pop();
                        prej = st2.top();
                        st2.pop();
                    }
                    st.push(j);
                    st2.push(prej);
                }
                while(!st.empty()) {
                    ans = max(ans, (m + 1 - st2.top()) * up[i][st.top()]);
                    st.pop();
                    st2.pop();
                }
            }
            printf("%d
    ", ans * 3);
        }
    }
    

    纯dp的方法就是这样:预处理每个点向左、向右的扩展距离,然后统一处理向上的扩展距离。

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n, m;
    int G[1005][1005];
    int U[1005][1005];
    int L[1005][1005];
    int R[1005][1005];
    
    int main() {
    #ifdef Yinku
        freopen("Yinku.in", "r", stdin);
    #endif // Yinku
        //freopen("citygame.in", "r", stdin);
        //freopen("citygame.out", "w", stdout);
        //int T;
        //scanf("%d", &T);
        int T = 1;
        while(T--) {
            scanf("%d%d", &n, &m);
            for(int i = 0; i <= n + 1; ++i) {
                memset(G[i], 0, sizeof(G[i][0]) * (m + 1));
            }
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    char tmp[2];
                    scanf("%s", tmp);
                    G[i][j] = (tmp[0] == 'F');
                }
            }
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    U[i][j] = 1;
                    L[i][j] = j;
                    R[i][j] = j;
                }
            }
    
            for(int i = 1; i <= n; ++i) {
                for(int j = 2; j <= m; ++j) {
                    if(G[i][j] == 1 && G[i][j - 1] == 1)
                        L[i][j] = L[i][j - 1];
                }
            }
    
            for(int i = 1; i <= n; ++i) {
                for(int j = m - 1; j >= 1; --j) {
                    if(G[i][j] == 1 && G[i][j + 1] == 1)
                        R[i][j] = R[i][j + 1];
                }
            }
    
            for(int i = 2; i <= n; ++i) {
                for(int j = 2; j <= m; ++j) {
                    if(G[i][j] == 1 && G[i - 1][j] == 1) {
                        U[i][j] = U[i - 1][j] + 1;
                        L[i][j] = max(L[i][j], L[i - 1][j]);
                        R[i][j] = min(R[i][j], R[i - 1][j]);
                    }
                }
            }
    
            int ans = 0;
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j)
                    ans = max(ans, U[i][j] * (R[i][j] - L[i][j] + 1));
            }
            printf("%d
    ", ans * 3);
        }
    }
    
  • 相关阅读:
    电子书下载:Pro jQuery
    神鬼传奇小技巧:教你如何修改自己想要的时装
    用虚拟机玩游戏的方法!! 开3D加速!
    如何让DevExpress的DateEdit控件正确显示日期的周名
    SOAP Version 1.2
    Delphi中的容器类
    <神鬼传奇>客户端终极优化精简方法
    今日阅读20090102基本数据结构
    判断一个char[]里是否包含两个连续的\r\n
    蛙蛙推荐:改进同步等待的网络服务端应用
  • 原文地址:https://www.cnblogs.com/Inko/p/11662754.html
Copyright © 2011-2022 走看看