201312-3 最大的矩形
思路
暴力枚举。f[i][j]表示由i到j拼成的最大矩形面积(第i块至第j块都参与组成矩形),其值等于该区间最小高度乘以区间长度。
AC代码如下
#include<cstdio>
int f[1000][1000]={0};//dp[i][j]表示i到j的最大面积
int main(){
int n,a[1000],ans=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){//初始化
f[i][i]=a[i];
}
for(int i=0;i<n;i++){
if(f[i][i]>ans) ans=f[i][i];//注意不要忘了判断dp[i][i]
for(int j=i+1;j<n;j++){
if(a[j]*(j-i)>f[i][j-1]){//这里n和高度a[j]范围保证了其积不会爆int。当然也可以作除法
f[i][j]=f[i][j-1]*(j-i+1)/(j-i);
}
else f[i][j]=a[j]*(j-i+1);
if(f[i][j]>ans) ans=f[i][j];
}
}
printf("%d\n",ans);
return 0;
}
(2019.9.8)
二刷本来合计能不能降降空间或者时间复杂度,半天没想出来还wa了…瑟瑟发抖
#include<cstdio>
#include<algorithm>
using namespace std;
int f[1005][1005];//f[i][j]表示区间[j,j+i)的最小高度
int main(){
int n,h[1005]={0},ans=0;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d",&h[i]);
}
fill(f[0],f[0]+1005*1005,10000);//初始化
for(int i=1;i<=n;i++){//枚举区间长度
for(int j=1;j<=n-i+1;j++){//区间起点
f[i][j]=min(f[i-1][j],h[j+i-1]);
ans=max(ans,f[i][j]*i);
}
}
printf("%d",ans);
return 0;
}