Codeforces 1136D Nastya Is Buying Lunch (贪心)

题意:给你和一个数组(是一个排列)和一些二元组,二元组(x, y)表示如果x正好在y前面而且相邻,那么x和y可以交换位置,问最后一个元素最多可以向前移动多少步?

思路:对于每个数,有两种选择,一种是向后走,一种是向前走。假设我们决定让这个数向前走,那么把所有以它结尾的二元组的cnt加1。cnt代表的是后面有多少个数可以与这个数合并。假设当前位置是i,若n - i - ans == cnt[i],说明这个数可以与最后一个数合并,ans加1。因为若满足这个等式,说明存在一种方法,让最后一个数恰好与i交换成功一次。

代码:

#include <bits/stdc++.h>
#define LL long long
#define lowbit(x) (x & (-x))
#define pii pair<int, int>
#define INF 0x3f3f3f3f
using namespace std;
const int maxn = 300010;
int cnt[maxn];
vector<int> c[maxn];
int a[maxn];
int main() {
	int n, m, x, y;
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	for (int i = 1; i <= m; i++) {
		scanf("%d%d", &x, &y);
		c[y].push_back(x);
	}
	for (int i = 0; i < c[a[n]].size(); i++)
		cnt[c[a[n]][i]]++;
	int ans = 0;
	for (int i = n - 1; i >= 1; i--) {
		if(n - i - ans == cnt[a[i]]) ans++;
		else {
			for (int j = 0; j < c[a[i]].size(); j++)
				cnt[c[a[i]][j]]++;
		}
	}
	printf("%d\n", ans);
} 

  

---恢复内容结束---

猜你喜欢

转载自www.cnblogs.com/pkgunboat/p/10520575.html