HDU1505 City Game(算竞进阶习题)

写了1506顺便写下1505。。

还是求矩形面积,不过要预处理一下以每一个F为底的高度,然后想左右扩展到最大长度即为矩形的长。。
计算方法有点绕,令l[i]表示i的左边界,那么初始化l[i] = i.

假设我们在第n行

每次向左跳 判断 h[j]是否小于或等于h[l[j] - 1],换句话说就是当前左边界已经满足小于关系了,我们再往左看一个长度,看是否还是满足小于或等于的关系

如果满足 则有l[j] = l[l[j]-1],可以理解为当前左边界往左一位满足条件,我们看左边界往左一位的左边界再往左一个长度是否也满足条件(因为是单调的,所以边界的边界一定满足条件)

需要自己琢磨。。。右边界同理

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
    int X = 0, w = 0; char ch = 0;
    while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
    while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
    return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C yql){
    A ans = 1;
    for(; p; p >>= 1, x = 1LL * x * x % yql)if(p & 1)ans = 1LL * x * ans % yql;
    return ans;
}
const int N = 200005;
int h[1005][1005], l[N], r[N];
char g[1005][1005];
int main(){

    int n, m, t;
    cin >> t;
    while(t --){
        while(cin >> n >> m){
            int ans = 0;
            memset(h, 0, sizeof h);
            memset(l, 0, sizeof l);
            memset(r, 0, sizeof r);
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= m; j++) cin >> g[i][j];
            }
            for(int j = 1; j <= m; j++) h[1][j] = g[1][j] == 'F' ? 1 : 0;
            for(int i = 2; i <= n; i++){
                for(int j = 1; j <= m; j++) h[i][j] = g[i][j] == 'R' ? 0 : h[i - 1][j] + 1;
            }
            for(int i = 1; i <= n; i++){
                for(int j = 1; j <= m; j++) l[j] = r[j] = j;
                for(int j = 2; j <= m; j++){
                    while(l[j] > 1 && h[i][j] <= h[i][l[j] - 1]) l[j] = l[l[j] - 1];
                }
                for(int j = m - 1; j >= 1; j--){
                    while(r[j] < m && h[i][j] <= h[i][r[j] + 1]) r[j] = r[r[j] + 1];
                }
                for(int j = 1; j <= m; j++){
                    ans = max(ans, (r[j] - l[j] + 1) * h[i][j]);
                }
            }
            printf("%d
", 3 * ans);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/onionQAQ/p/10519874.html