DP46题中的一道,刚开始用错误的状态转移方程DP[i]=max(h[i],h[i]+DP[i])来做,后来发现大错特错,应该不断迭代边界找到每块木板两边连续的不比他短的木板的数目,然后可以通过s=h[i]*(r[i]-l[i]+1)得出一个以当前木板为最短木板的面积,然后求得最大值即可.
代码如下
#include <stdio.h>
#include <string.h>
int n;
__int64 h[100100];
int l[100100], r[100100];
int main()
{
while(scanf("%d", &n) && n)
{
for(int i = 0; i < n; i++)
{
scanf("%I64d", &h[i]);
}
for(int i = 0; i < n; i++)
{
l[i] = i; //将左边界初始化为当前木板
while(l[i] - 1 >= 0 && h[l[i] - 1] >= h[i]) //假如当前左边界l[i]左边的木板l[i]-1比l[i]长
l[i] = l[l[i]-1]; //则可将l[i]更新为木板l[i]-1的左边界即l[l[i]-1]
}
for(int i = n-1; i >=0; i--)
{
r[i] = i;
while(r[i] +1 <n && h[r[i] +1] >= h[i]) //同左边界的处理方法,不断迭代求得右边界
r[i] = r[r[i]+1];
}
__int64 Max=0,k;
for (int i=0;i<n;i++)
{
k=(r[i]-l[i]+1)*h[i]; //对于h[i],求得以它为最短边的矩形的面积,刷新Max值
if (k>Max)
Max=k;
}
printf("%I64d\n",Max);
}
return 0;
}