• 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);
        }
    }
    
  • 相关阅读:
    hdu 1254 推箱子(双重bfs)
    hdu 1495 非常可乐 (广搜)
    [leetcode-687-Longest Univalue Path]
    [leetcode-686-Repeated String Match]
    POJ 2287 田忌赛马 贪心算法
    [leetcode-304-Range Sum Query 2D
    [leetcode-682-Baseball Game]
    [leetcode-299-Bulls and Cows]
    [leetcode-319-Bulb Switcher]
    [leetcode-680-Valid Palindrome II]
  • 原文地址:https://www.cnblogs.com/Inko/p/11662754.html
Copyright © 2020-2023  润新知