ABC 203 E - White Pawn

E - White Pawn

DP

\(st[y]\) 表示 \((2*n,y)\) 是否能到达

初始化 \(st[n]=true\)

  1. \((x,y)\) 是白子,则 \(st[y]\) 的值为 \(y\) 这一列的上一个黑子的值

  2. \((x,y)\) 是黑子,则 \(st[y]=st[y-1]\;or\;st[y+1]\)

所以将 黑子按 \(x\) 从小到大排序,不断更新 \(st\) 即可

但若两个黑子在同一行且相邻,它们的只应该与这一行之前最近的 \(y-1,y+1\) 的黑子的值有关

但按上述转移则求完一个黑子后,\(st[y]\) 被更新了,那下一个黑子用到的 \(st\) 值已经被覆盖了

所以可以对于每一行的 \(y\), 先把他们的答案放到 \(tmp\) 中,这一行都更新完了再给 \(st\) 赋值

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
typedef long long ll;

const int N = 2e5 + 10;
int n, m;
map<int, vector<int> > mp;
map<int, bool> st;
int main()
{
	ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++)
	{
		int x, y;
		cin >> x >> y;
		mp[x].push_back(y);
	}
	for (auto [i, vt] : mp)
		sort(vt.begin(), vt.end());
	st[n] = true;
	for (auto [i, vt] : mp)
	{
		map<int, bool> tmp;
		for (auto y : vt)
			tmp[y] = st[y-1] | st[y+1];
		for (auto [y, s] : tmp)
			st[y] = tmp[y];
	}
	int ans = 0;
	for (auto [y, s] : st)
		ans += s;
	cout << ans << endl;
	return 0;
}

posted @ 2022-05-23 14:20  hzy0227  阅读(37)  评论(0编辑  收藏  举报