1. 程式人生 > >Codeforces Round #546 (Div. 2) D 貪心 + 思維

Codeforces Round #546 (Div. 2) D 貪心 + 思維

題解 -- tps make cout ++ 一個隊列 一個 def

https://codeforces.com/contest/1136/problem/D
貪心 + 思維

題意

你面前有一個隊列,加上你有n個人(n<=3e5),有m(m<=個交換法則,假如u在v相鄰前面,那麽u和v可以交換位置,問你是隊列最後一個人的時候你最前可以換到前面哪裏

題解

  • 因為相鄰才能換,所以最後一個換到前面一定是一步一步向前走,所以不存在還要向後走的情況
  • 設最後一個為u,假設前面有一個能和u換位置的集合,那麽需要將這些點盡量往後移動去接u
  • 假設前面有一個不能和u換位置的集合S,那麽u和S的順序永遠不會換過來
  • 從後向前遍歷,對於每個點假設後面緊接著S+u,假如這個點能和S+u換位置,那麽u可以向前移動一格,ans++
  • 假如不行,則將這個加入S
#include<bits/stdc++.h>

using namespace std;
int n,m,a[300005],u,v,i,ok,ans;
vector<int>A;set<pair<int,int> >vi;
int main(){
    cin>>n>>m;
    for(i=1;i<=n;i++)cin>>a[i];
    for(i=0;i<m;i++){
        cin>>u>>v;
        vi.insert(make_pair(u,v));
    }
    A.push_back(a[n]);
    for(i=n-1;i>=1;i--){
        ok=1;
        for(auto x:A){
            if(!vi.count(make_pair(a[i],x))){ok=0;break;}
        }
        if(ok)ans++;
        else A.push_back(a[i]);
    }
    cout<<ans;
}

Codeforces Round #546 (Div. 2) D 貪心 + 思維