动态规划求最大子矩阵
对于hdu 1505,1506,都是求关于最大子矩阵的问题,因为n为1000,n^3必然超时,因此需要优化,这类题应用了一种特殊的优化算法使时间复杂度降到了n*n。
优化算法
因为求最大子矩阵,都需要求最左边比该点高的位置,最右边比该点高的位置。因此就先假如我们现在我们求l[n],很明显现在l[1……n-1]都已经求出来了,那么我们就可以利用前面求得的对其进行优化,同理求r[n]。
优化的代码:
l[1] = 1;
for(int i = 2; i <= n; i++)
{
int t = i;
while(t > 1 && h[t-1] >= h[i])
t = l[t-1];
l[i] = t;
}
r[n] = n;
for(int i = n-1; i >= 1; i–)
{
int t = i;
while(t < n && h[t+1] >= h[i])
t = r[t+1];
r[i] = t;
}
因此1506题就可以得出,代码为:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
const int maxn = 100005;
LL l[maxn],r[maxn],h[maxn];
int main()
{
int n;
while(scanf("%d", &n) != EOF && n)
{
for(int i = 1; i <= n; i++)
scanf("%I64d", &h[i]);
l[1] = 1;
for(int i = 2; i <= n; i++)
{
int t = i;
while(t > 1 && h[t-1] >= h[i])
t = l[t-1];
l[i] = t;
}
r[n] = n;
for(int i = n-1; i >= 1; i--)
{
int t = i;
while(t < n && h[t+1] >= h[i])
t = r[t+1];
r[i] = t;
}
LL ans = 0;
for(int i = 1; i <= n; i++)
ans = max(ans, h[i]*(r[i]-l[i]+