CodeForces547 B.Mikeと足(モノトーンスタック/ DP)

質問の意味:

アレイの所与の長さNは、N <= 2E5
最大のF(L、R)間の最小の数であり、[Lは、R]であり、ANS(k)の定義(F(L、L +と K-1))、 前記1 <= L <= NK、すなわちANS(K)セクションF kの最大長さです。
今1の要求出力順序がkにN、ANS(k)の値

アイデア:

Lとの(i)およびR(I)は、i番目の左右の境界で最小値を記録拡張することができ、ANS(1)を更新しようとすることが可能である(I)-L(とANS(R(I)とI)+1)、
間隔の[L(I)、R(ので I)]は、A(i)が最小間隔は、(i)である含みます。
(I)更新(R(I)-L(ANS各第 I)+1)、 ANS(I)= MAX(:リスト再帰の最後の ANS(I)、ANS(I + 1)) 、同(大間隔がセル間を含有します)。

L(i)を計算すると、R(i)が単調スタックを考えるのは簡単ですが、DPは(コードを参照)を書くことができます。

コード(DP):

#include<bits/stdc++.h>
using namespace std;
const int maxm=2e5+5;
int l[maxm],r[maxm];
int a[maxm];
int ans[maxm];
signed main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    a[0]=a[n+1]=-1;
    for(int i=1;i<=n;i++){
        int j=i-1;
        while(a[i]<=a[j])j=l[j];
        l[i]=j;
    }
    for(int i=n;i>=1;i--){
        int j=i+1;
        while(a[i]<=a[j])j=r[j];
        r[i]=j;
    }
    for(int i=1;i<=n;i++){
        l[i]++;
        r[i]--;
    }
    for(int i=1;i<=n;i++){
        int len=r[i]-l[i]+1;
        ans[len]=max(ans[len],a[i]);
    }
    for(int i=n-1;i>=1;i--){
        ans[i]=max(ans[i],ans[i+1]);
    }
    for(int i=1;i<=n;i++){
        cout<<ans[i]<<' ';
    }
    return 0;
}
公開された430元の記事 ウォン称賛36 ビュー20000 +

おすすめ

転載: blog.csdn.net/weixin_44178736/article/details/104688275