http://acm.hdu.edu.cn/showproblem.php?pid=1506
一道比较神奇的动归题目,没有严格的状态方程,只是提前用一种类似链表的方式预处理。
没能找出自己的错误:
自己的:
#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define MAXN 100000+50
long h[MAXN];
int N,L[MAXN],R[MAXN];
int main()
{
while(scanf("%d",&N)&&N)
{
int i;
for(i=0;i<N;i++)
scanf("%ld",&h[i]);
int j,k;
for(j=0;j<N;j++)
{
int flag1=0,flag2=0;
for(k=j-1;k>=0;k--)
{if(h[k]<h[j])
{ L[j]=k;
flag1=1;
break;
}
}
for(k=j+1;k<N;k++)
{if(h[k]<h[j])
{
R[j]=k;
flag2=1;
break;
}
}
if(flag1==0)L[j]=-1;
if(flag2==0)R[j]=N;
}
int t;
LL ans=0;
int p=0;
for(t=0;t<N;t++)
{
LL tmp;
if((R[t]==N&&L[t]!=-1)||(R[t]!=N&&L[t]==-1))
tmp=(R[t]-L[t])*h[t];
else tmp=(R[t]-L[t]+1)*h[t];
ans=max(ans,tmp);
p=t;
}
printf("%I64d\n",ans);
}
return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define LL long long
#define MAXN 100000+50
long h[MAXN];
int N,L[MAXN],R[MAXN];
int main()
{
while(scanf("%d",&N)&&N)
{
int i;
for(i=0;i<N;i++)
scanf("%ld",&h[i]);
int j,k;
for(j=0;j<N;j++)
{
int flag1=0,flag2=0;
for(k=j-1;k>=0;k--)
{if(h[k]<h[j])
{ L[j]=k;
flag1=1;
break;
}
}
for(k=j+1;k<N;k++)
{if(h[k]<h[j])
{
R[j]=k;
flag2=1;
break;
}
}
if(flag1==0)L[j]=-1;
if(flag2==0)R[j]=N;
}
int t;
LL ans=0;
int p=0;
for(t=0;t<N;t++)
{
LL tmp;
if((R[t]==N&&L[t]!=-1)||(R[t]!=N&&L[t]==-1))
tmp=(R[t]-L[t])*h[t];
else tmp=(R[t]-L[t]+1)*h[t];
ans=max(ans,tmp);
p=t;
}
printf("%I64d\n",ans);
}
return 0;
}
别人的:
#include<iostream>
using namespace std;
int a[100010];
int l[100010];
int r[100010];
int main(){
int n;
while(scanf("%d",&n)!=EOF&&n){
memset(a,0,sizeof(a));
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++){
l[i]=i;
while(l[i]>0&&a[l[i]-1]>=a[i]) l[i]=l[l[i]-1];
}
for(int i=n-1;i>-1;i--){
r[i]=i;
while(r[i]<n-1&&a[r[i]+1]>=a[i]) r[i]=r[r[i]+1];
}
long long max=0;
long long m;
for(int i=0;i<n;i++){
m=(long long)(r[i]-l[i]+1)*a[i];
if(max<m) max=m;
}
cout<<max<<endl;
}
return 0;
}