CodeFoces 546-D(greedy 贪心)

版权声明:欢迎评论与转载,转载时请注明出处! https://blog.csdn.net/wjl_zyl_1314/article/details/88737763

–>题目传送门<–
题意:
现在有编号从1到n的人站成一个队列,对列顺序由输入得到。
然后给出许多对(u,v)表示如果u站在v前方,则u和v可以换位置。
Nastya此时站在最后,问她最多能向前移动多少位?
题解:
贪心点想:
如果Nastya可以与前面的人交换,那就直接交换是最好的,因为当前的最好结果就是向前一步;
如果不能交换,就看能和Nastya交换的人能否到Nastya的前面,如果能,Nastya则也可以向前一步,而如何判断能否交换呢?
需要一个数组num来记录第i个人后面能与其交换的人数,如果能交换的人数恰好等于Nastya前的一个位置则说明能够交换到Nastya前一位。那么Nastya向前移一位。
AC代码:

#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int maxn=3*1e5+5;
int a[maxn],num[maxn],ans=0;
vector <int >v[maxn];
int main()
{
    ios::sync_with_stdio(false);
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=m;i++)
    {
        int uu,vv;
        cin>>uu>>vv;
        v[vv].push_back(uu);
    }
    for(int i=0;i<(int)v[a[n]].size();i++)
        num[v[a[n]][i]]++;//初始化记录
    for(int i=n-1;i>=1;i--)
    {
        if(num[a[i]]==n-i-ans)ans++;//如果能交换,则向前一步
        else
        {
            for(int j=0;j<(int)v[a[i]].size();j++)
            num[v[a[i]][j]]++;
        }
    }
    cout <<ans<< endl;
    return 0;
}

欢迎评论!

猜你喜欢

转载自blog.csdn.net/wjl_zyl_1314/article/details/88737763