トピックリンク:http://poj.org/problem?id=2559
アイデア:単調なスタック
単調なスタックとは何ですか?
単調なスタックも単調単調減少スタックおよびスタックを増加さに分割されているように、名前からそれを聞いた、スタック単調に格納されたデータは、順序付けされなければなりません
・単調に増加するスタック:スタックが単調に増加する配列の配列です
・単調減少スタック:スタックが単調に減少する配列の配列です
PS:ここでは、前記配列の緩やかな増加と減少を注意しなければならない、むしろデータスタック内の順序よりも、スタックを意味します
なぜ、この質問は単調スタックすることができますか?
左から右に長方形の仮定の高さがインクリメントされ、その後、答えはどのくらいですか?明らかに、我々は、矩形の最終的な高さは、各矩形の高さに試すことができ、矩形形状を与えるために、右境界まで延びる幅は、最大値は、すべてのそのような矩形領域に答えであるとります。
新たに追加さより矩形小さい場合は、長方形の高さは、必ずしもその前に、増加されていない計算無用の背面に矩形の高さ。
具体的な実装は、単純に前の矩形のその幅の累積合計が答えを更新するために短い長方形の高さを掛けながら、新しい矩形の矩形よりも遭遇下を知っているポップよりも高くなっています。この方法では、最終的にすべてのRectangleが答えを更新するために、フライアウト置きます。
ACコード
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
#define ll long long
#define N 100005
ll s[N],w[N],a[N];//s为栈,w为宽度,a为高度
int top=0;
void init()//初始化
{
memset(s,0,sizeof(s));
memset(w,0,sizeof(w));
memset(a,0,sizeof(a));
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n!=0)
{
init();
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
ll ans=0;
a[n+1]=top=0;
for(int i=1;i<=n+1;i++)
{
if(a[i]>=s[top])//单调队列
{
s[++top]=a[i];
w[top]=1;
}
else
{
ll tmp=0;
while(a[i]<s[top])
{
tmp+=w[top];
ans=max(ans,tmp*s[top]);//更新最大值
top--;
}
s[++top]=a[i];
w[top]=tmp+1;
}
}
printf("%lld\n",ans);
}
return 0;
}
参考資料
「アルゴリズムコンテストステップアップガイド」河南電子オーディオビジュアル李Yudongを公開・