羅区[P4393]シーケンス

タイトル効果:長さNのシーケンスを考えるとは、隣り合う要素が2つの値の大きい方のコストで組み合わせることができ、双方の積分後の値も大きい値、合わせた要求でありますN-最小コストの後に数字の1です。

ソリューション:
最大に加えて、それぞれの値は、これだけの組み合わせコストが左最大値と右の最大値が小さいということでなければならない、一度統合されます。どのように問題を解決するために、各要素の左と右に変換することは、第1の要素の値よりも大きい場合、単調なスタックは再びそれを掃引します。
注:例えば4223と同じ要素、場合、2つの中間体2は、最終的な答えを計算する際にエラーを生成する計算値を回避する方法を取る左より大きい、等しい取ら各要素の右側よりも大きくなっています。

コードは以下の通りです

#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
const int inf=0x3f3f3f3f;
typedef long long LL;

int n,a[maxn],l[maxn],r[maxn],stk[maxn],top;
LL ans;

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    
    a[0]=a[n+1]=inf;
    for(int i=1;i<=n+1;i++){
        while(top&&a[stk[top]]<=a[i])r[stk[top--]]=i;
        stk[++top]=i;
    }
    top=0;
    for(int i=n;~i;i--){
        while(top&&a[stk[top]]<a[i])l[stk[top--]]=i;
        stk[++top]=i;
    }
    for(int i=1;i<=n;i++){
        if(l[i]<1&&r[i]>n)continue;
        if(l[i]>=1&&r[i]<=n)ans+=min(a[l[i]],a[r[i]]);
        else if(r[i]>n)ans+=a[l[i]];
        else if(l[i]<1)ans+=a[r[i]];
    }
    printf("%lld\n",ans);
    return 0;
}

おすすめ

転載: www.cnblogs.com/wzj-xhjbk/p/10950324.html