• HDU1506 Largest Rectangle in a Histogram 动态规划


    先粘上TLE的代码,先对高度离散化,然后DP高度求解。复杂度过高。

    代码如下:

    View Code
    #include <cstdlib>
    #include <cstdio>
    #include <cstring>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #define MAXN 100005
    using namespace std; 
    int N, cnt;
    
    int seq[MAXN], cseq[MAXN];
    long long dp[MAXN]; 
    map<int,int>mp, rmp; 
    
    void getint( int &c )
    {
        char chr;
        while( chr= getchar(), chr< '0'|| chr> '9' ) ;
        c= chr- '0';
        while( chr= getchar(), chr>= '0'&& chr<= '9' )
        {
            c=c* 10+ chr- '0';
        }
    } 
    
    inline long long DP()
    {
        long long Max = 0;
        for (int i = 0; i < N; ++i) {
            for (int j = 1; j <= mp[seq[i]]; ++j) {
                dp[j] += rmp[j];
                Max = max(Max, dp[j]);
            }
            for (int j = mp[seq[i]]+1; j <= cnt; ++j) {
                dp[j] = 0;
            }
        }
        return Max;
    }
    
    int main()
    {
        int Max;
        while (scanf("%d", &N), N) {
            cnt = 0;
            memset(dp, 0, sizeof (dp));
            mp.clear(), rmp.clear();
            for (int i = 0; i < N; ++i) {
                getint(seq[i]);
                cseq[i] = seq[i];    
            }
            sort(cseq, cseq+N);
            for (int i = 0; i < N; ++i) {
                if (mp.count(cseq[i]) == 0) {
                    mp[cseq[i]] = ++cnt;
                    rmp[cnt] = cseq[i];
                }
            }
            printf("%I64d\n", DP());
        }
        return 0;
    }

    后来依据更犀利的解法来构造状态,l[i], r[i],通过维护这两个数组来达到目的。其代表的含义即是当前高度所能够延伸的最左边和最右边。

    代码如下:

    #include <cstdlib>
    #include <cstdio>
    #include <cstring> 
    #include <iostream> 
    #define MAXN 100005
    using namespace std;
    
    int N, seq[MAXN], l[MAXN], r[MAXN];
    
    inline long long max(long long x, long long y)
    {
        return x > y ? x : y;
    }
    
    long long DP()
    {
        long long Max = 0;
        for (int i = 2; i <= N; ++i) {
            while (seq[l[i]-1] >= seq[i]) {
                l[i] = l[l[i]-1];
                if (l[i] <= 0) break; // 前面没有加这句话,TLE
            }
        }
        for (int i = N-1; i >= 1; --i) {
            while (seq[r[i]+1] >= seq[i]) {
                r[i] = r[r[i]+1];
                if (r[i] >= N) break;
            }
        }
        for (int i = 1; i <= N; ++i) {
            Max = max(Max, (long long)(1)*seq[i]*(r[i]-l[i]+1));
        }
        return Max;
    }
    
    int main()
    {
        while (scanf("%d", &N), N) {
            for (int i = 1; i <= N; ++i) {
                scanf("%d", &seq[i]); 
                l[i] = r[i] = i;
            }
            printf("%I64d\n", DP());
        }
        return 0;
    }
  • 相关阅读:
    响应式笔记(1)
    javascript复制文章加版权声明代码
    div的水平和垂直居中
    javascript随机打乱数组
    javascript操作字符串的方法
    《Javascript高级程序设计》读书笔记(1-3章)
    一个将 footer 保持在底部的最好方法
    Python内置的字符串处理函数整理
    c c++怎么判断一个字符串中是否含有汉字
    shell的if判断
  • 原文地址:https://www.cnblogs.com/Lyush/p/2454289.html
Copyright © 2020-2023  润新知