HDU 1506

【题目大意】

  给出n(n<=100000)个木板的高度,宽度均为1,将n个木板竖成一排,在上面截取长方形,求最大面积。

 

【解题思路】

 

  对于每一块木板,Area=height[i]*(j-k+1)  设其中任一块x,  j<=x<=k,  height[x]>=height[i]; 找j,k成为关键。

  一般方法肯定超时,

[cpp:firstline[1]]  view plain copy
  1. FOR i:=1 TO n  
  2.     FOR j:=1 TO n  
  3.         k:=Min height[i TO j] ;   
  4.         area:=height[k]*(j-i+1);  
  5.     END FOR  
  6. END FOR  
  7. return Max area;  
  

 

利用动态规划,如果它左边高度大于等于它本身,那么它左边的左边界一定满足这个性质,再从这个边界的左边迭代下去

[cpp:firstline[1]]  view plain copy
  1. for(i=1;i<=n;i++) {   
  2.        while(a[l[i]-1]>=a[i])   
  3.               l[i]=l[l[i]-1];  
  4. }  
  5. for(i=n;i>=1;i–) {   
  6.        while(a[r[i]+1]>=a[i])   
  7.               r[i]=r[r[i]+1];   
  8. }  
 

 

PS: 1. 题目中height可能为0,初始化height数组为-1,防止死循环。

      2. 结果可能超出int,height初始为__int64 或运算前强转化为__int64。运算过程中int会溢出。

 

【代码】

#include <cstdio>
#include <cstring>
#define maxn 100010
int l[maxn],r[maxn],n,i;
int main()
{
	__int64 a[maxn],max,area;
	while(scanf("%d",&n)&&n!=0){
		for(i=1;i<=n;i++){
			scanf("%I64d",&a[i]);
			l[i]=r[i]=i;//l[i]表示左边边界,r[i]表示右边边界
		}
		a[0]=a[n+1]=-1;
		for(i=1;i<=n;i++)
			while(a[l[i]-1]>=a[i])
				l[i]=l[l[i]-1];
		for(i=n;i>=1;i--)
			while(a[r[i]+1]>=a[i])
				r[i]=r[r[i]+1];
		for(i=1,max=0;i<=n;i++){
			area=(r[i]-l[i]+1)*a[i];
			max=area>max?area:max;
		}
		printf("%I64d\n",max);
	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值