Psychos in a Line(CF #189 Div. 1)

集訓的時候考這道題,現場做到這道題時沒什麼思路,過幾天重看之後,還是沒什麼思路,然後上網搜了一下,發現用的是單調隊列,趕緊補了一下單調隊列的知識,接着又看了一下這道題,想了一會,好像有一點明白了。在此記下這道有意思的題。

題目大意:有n個被編了號的人,如果左邊的人的編號比右邊的人的編號大,則左邊的人可以殺了右邊的人,注意,人可以同時被殺。題目描述比較簡單,容易看懂這裏就不再贅述了。附鏈接http://codeforces.com/problemset/problem/319/B

大體思路:開闢一個數組num[100005]用於記錄各個編號所對應的人被殺的順序(即第幾輪被殺),如果編號爲 i 的人第一輪就被殺,則num[i]=1,當然,沒被殺num[i]=0,再用一個 vector 數組維持單調遞減的隊列,它的作用在於,如果輸入一個數比隊列裏的最後一個數大,說明輸入的這個數被殺的順序在隊列最後一個之後,然後彈出最後一個數,繼續向前比較,這就是單調隊列在這裏的用處。當然我不知道是否還有其它思路,也許可以不用單調隊列。

下面是ac代碼:

#include<iostream>
#include<vector>
#include<cstring>
using namespace std;

int num[100005];
vector<int> v;
int main(){
    int n;
    while(cin>>n){
        int a;
        v.clear();
        memset(num,0,sizeof(num));
        for(int i=0;i<n;i++){
            cin>>a;
            int cnt=0;  //記錄編號爲i的人在第幾輪被殺
            if(v.empty())
                v.push_back(a);
            else{
                while(v.back()<a){
                    cnt=max(cnt,num[v.back()]);
                    v.pop_back();
                    if(v.empty())
                        break;
                }
                if(v.empty())
                    v.push_back(a);
                else{
                    num[a]=cnt+1;
                    v.push_back(a);
                }
            }
        }
        int maxn=0;
        for(int i=0;i<n;i++)
            maxn=max(maxn,num[i]);
        cout<<maxn<<endl;
    }
    return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章