HDU-1506 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;

}

你可能感兴趣的:(动态规划)