アルゴリズム競争上級ガイド--- 0x18(モノトーンスタック)シティゲーム

トピック

ここに画像の説明を挿入

回答

ここに画像の説明を挿入

  1. 各行を列挙し、この行の各列に連続するFの数を記録できます(4行目の列挙に示されているように)。Fの数は最初の行から再帰的に計算できるため、問題は次のように変換されます。アルゴリズムの競争。ご注文ガイド-0x11を(スタック)ヒストグラムの最大の長方形
  1. 各行について、各高さで形成できる最大の面積を持つ長方形を列挙し、最大値をとることができます。質問の例を見てください。4番目の列では、4以上の左側と右側の高さのみが列挙される長方形を形成できるため、左側と右側の小さな長方形の最小の高さが必要です。ご覧のとおり、4になると、左がありません。右に2なので、面積は(7-3-1)* 4 = 12です。
  1. 次に、変換は、左側で彼に最も近く、その高さよりも小さい添え字を記録でき、右側で彼に最も近く、その高さよりも小さい添え字を記録できる場合、(right-left-1)は対応する最長の長さですこの高さまで、これは単なる単調なスタックアプリケーションではありませんか?

コード

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 1010;

int n, m;
char g[N][N];
int f[N][N];


int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    cin >> n >> m;

    for (int i = 1; i <= n; i++) {
    
    
        for (int j = 1; j <= m; j++) {
    
    
            cin >> g[i][j];
            if (g[i][j] == 'F') f[i][j] = f[i - 1][j] + 1;
            else f[i][j] = 0;
        }
    }

    int res = 0;
    for (int i = 1; i <= n; i++) {
    
    

        int stk[N], tt = 0, l[N], r[N];
        for (int j = 1; j <= m; j++) {
    
    
            while (tt && f[i][stk[tt]] >= f[i][j]) tt--;
            if (tt) l[j] = stk[tt];
            else l[j] = 0;
            stk[++tt] = j;
        }

        tt = 0;
        for (int j = m; j > 0; j--) {
    
    
            while (tt && f[i][stk[tt]] >= f[i][j]) tt--;
            if (tt) r[j] = stk[tt];
            else r[j] = m + 1;
            stk[++tt] = j;
        }

        for (int j = 1; j <= m; j++) {
    
    
            res = max(res, (r[j] - l[j] - 1) * f[i][j]);
        }
    }

    cout << res * 3 << endl;

    return 0;
}

おすすめ

転載: blog.csdn.net/qq_44791484/article/details/113984298