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; }