codeforces 1136D Nastya Is Buying Lunch (贪心+模拟)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wwwlps/article/details/88679980

题目大意: 给定一个1~n的排列,和m对可以交换的组合(有顺序,1 2的话表示在前面的1可以和相邻的2交换位置,而如果2在前面则不能),问变换之后最后一个数通过可以最大前移多少位。

题目解答:

嗯......我们先想一下,从后往前看,如果离p[n]最近的满足交换的数是否应该优先换到p[n]的前面(如果可以的话)呢?你想一下,如果前面一个位置下标为i的数换到了位置下标为i+q的地方,i和i+q之间的数的相对顺序是不会改变的,这对p[n]来说也是没有影响的,这个有点类似于冒泡,所以我们与其先和离p[n]较远的数交换,不如先换近的。

代码:

#include <iostream>
#include <set>
#include <vector>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn=300005;
const int maxz=500005;
int p[maxn];
int book[maxn];
int n,m;
vector<int>v[maxn];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        cin>>p[i];
    }
    for(int i=0;i<m;i++)
    {
        int x,y;
        cin>>x>>y;
        v[x].push_back(y);
    }
    int nowp=n-1;
    book[p[n-1]]=1;
    int ans=0;
    for(int i=n-2;i>=0;i--)
    {
        int e=p[i];
        int cnt=0;
        for(int j=0;j<v[e].size();j++)
        {
            int u=v[e][j];
            if(book[u])
            {
               cnt++;
            }
        }
        if(cnt+i==n-1-ans)
            ans++;
        else
            book[e]=1;
    }
    cout << ans << endl;
    return 0;
}

map<int,bool>mmp[maxn]也可以用来存储键值对是否存在,这里用的vector

猜你喜欢

转载自blog.csdn.net/wwwlps/article/details/88679980