首页 > 其他分享 >AtCoder Regular Contest 119 F AtCoder Express 3

AtCoder Regular Contest 119 F AtCoder Express 3

时间:2023-05-02 17:12:27浏览次数:48  
标签:AtCoder typedef int text long Regular gets 119

洛谷传送门

AtCoder 传送门

很厉害的题!

考虑所有车站已确定,如何求 \(0\) 到 \(n+1\) 的最短路。设 \(g_{i,0}\) 为只考虑 \(0 \sim i\) 的点,到 \(i\) 和它左边第一个 \(\text{A}\) 的最短路,\(g_{i,1}\) 同理。有转移:

  • 若 \(s_{i-1} = \text{A}, s_i = \text{A}, g_{i,0} \gets g_{i-1,0} + 1\)
  • 若 \(s_{i-1} = \text{A}, s_i = \text{B}, g_{i,0} \gets \min(g_{i-1,0}, g_{i-1,1} + 2)\)
  • 若 \(s_{i-1} = \text{B}, s_i = \text{A}, g_{i,0} \gets \min(g_{i-1,0} + 1, g_{i-1,1} + 1)\)
  • 若 \(s_{i-1} = \text{B}, s_i = \text{A}, g_{i,0} \gets g_{i-1,0}\)

\(g_{i,1}\) 的转移是对称的。

设 \(f_{i,x,y,0/1}\) 表示当前考虑了 \(0 \sim i\) 的车站,\(g_{i,0} = x, g_{i,1} = y\),\(s_i\) 为 \(\text{A}\) 或 \(\text{B}\) 的方案数。这是 \(O(n^3)\) 的。

考虑压状态。显然遇到 \(\text{ABB...B}\) 时 \(x,y\) 相差就会很大。但是要到达最后一个 \(\text{B}\),可以先跳一步 \(\text{A}\) 再往回走。这是我们的最终目标,我们不关心途中的最短路数值究竟是什么。因此可以做出如下优化:当 \(x \ge y + 2\) 时,强制让 \(x \gets y + 2\),\(y\) 同理。这样不会影响最终答案。这样是 \(O(n^2)\) 的。

实现时用 unordered_map 记录所有状态有效。

code
// Problem: F - AtCoder Express 3
// Contest: AtCoder - AtCoder Regular Contest 119
// URL: https://atcoder.jp/contests/arc119/tasks/arc119_f
// Memory Limit: 1024 MB
// Time Limit: 4000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>
#define pb emplace_back
#define fst first
#define scd second
#define mems(a, x) memset((a), (x), sizeof(a))

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ldb;
typedef pair<int, int> pii;

const int maxn = 4010;
const int mod = 1000000007;

int n, m;
char s[maxn];
unordered_map<int, int> f[2][maxn][2];

inline void upd(int o, int x, int y, int k, int val) {
	x = min(x, y + 2);
	y = min(y, x + 2);
	int &p = f[o][x][k][y];
	p += val;
	(p >= mod) && (p -= mod);
}

void solve() {
	scanf("%d%d%s", &n, &m, s + 1);
	--n;
	if (s[1] != 'B') {
		f[1][1][0][0] = 1;
	}
	if (s[1] != 'A') {
		f[1][0][1][1] = 1;
	}
	for (int i = 2, o = 0; i <= n; ++i, o ^= 1) {
		for (int x = 0; x <= n + 2; ++x) {
			for (int k = 0; k <= 1; ++k) {
				f[o][x][k].clear();
			}
		}
		for (int x = 0; x <= n + 2; ++x) {
			for (pii p : f[o ^ 1][x][0]) {
				int y = p.fst, val = p.scd;
				if (s[i] != 'B') {
					upd(o, x + 1, y, 0, val);
				}
				if (s[i] != 'A') {
					upd(o, min(x, y + 2), min(x + 1, y + 1), 1, val);
				}
			}
			for (pii p : f[o ^ 1][x][1]) {
				int y = p.fst, val = p.scd;
				if (s[i] != 'B') {
					upd(o, min(x + 1, y + 1), min(x + 2, y), 0, val);
				}
				if (s[i] != 'A') {
					upd(o, x, y + 1, 1, val);
				}
			}
		}
	}
	int ans = 0;
	for (int x = 0; x <= n; ++x) {
		for (int k = 0; k <= 1; ++k) {
			for (pii p : f[n & 1][x][k]) {
				int y = p.fst, val = p.scd;
				if (min(x, y) + 1 <= m) {
					ans = (ans + val) % mod;
				}
			}
		}
	}
	printf("%d\n", ans);
}

int main() {
	int T = 1;
	// scanf("%d", &T);
	while (T--) {
		solve();
	}
	return 0;
}

标签:AtCoder,typedef,int,text,long,Regular,gets,119
From: https://www.cnblogs.com/zltzlt-blog/p/17367912.html

相关文章

  • AtCoder Regular Contest 119 D Grid Repainting 3
    洛谷传送门AtCoder传送门对每个红格的行和列连边,建出二分图。对于二分图中的每个连通块分别考虑。大胆猜测对于每个连通块,我们都能够进行适当的操作,使得只有一行/一列没被操作(显然不能使所有行和列都被操作)。对应的方案就是随便取一棵生成树,把不被染白的那一行/列拎出来当根,然......
  • AtCoder Regular Contest 117 F Gateau
    洛谷传送门AtCoder传送门差分约束算法:给出\(m\)个不等式形如\(x_{a_i}\lex_{b_i}+y_i\),求是否有解。考虑把不等式看成图上的三角不等式\(dis_v\ledis_u+d\),连边\((b_i,a_i,y_i)\),以\(x_i\)最大的位置跑最短路,如果图中有负环就无解。此时求出来的\(dis_i\)......
  • Atcoder Grand Contest 059 E - Grid 3-coloring(转化+思维)
    首先先是一步很猛的操作——将三染色视作构造一个矩阵使得相邻元素相差\(1\)且每个元素\(\bmod3\)的值就等于其颜色。证明是显然的,我们按从上到下从左到右的顺序填数,可以归纳证明,对于一个相邻格子颜色互不相同的矩阵的填数方案,处于斜对角的两个格子上写的数要么差\(2\),要么......
  • Mastering Regular Expressions(精通正则表达式) 阅读笔记:第一章,概念
    RealScenario(现实场景)Here'sthescenario:you'regiventhejobofcheckingthepagesonawebserverfordoubledwords(suchas"thisthis"),acommonproblemwithdocumentssubjecttoheavyediting.任务:检查文本中重复的单词(doubledwords),比如&q......
  • AtCoder Regular Contest 122 D XOR Game
    洛谷传送门AtCoder传送门从高到低按位考虑。设当前位有\(k\)个\(1\)。如果\(k\bmod2=0\),这意味着Alice如果选了一个数,Bob可以选相同的数。发现可以分成\((0,0),(1,1)\)两组,递归下去即可。如果\(k\bmod2=1\),意味着答案这一位一定是\(1\)(因为无论如何都不......
  • AtCoder Regular Contest 119 E Pancakes
    洛谷传送门AtCoder传送门感觉挺典的,为啥有2500啊(观察发现,反转序列对\(\sum\limits_{i=1}^{n-1}|a'_i-a'_{i+1}|\)影响不大。具体而言,设反转了\(a_l\sima_r\),记\(s=\sum\limits_{i=1}^{n-1}|a_i-a_{i+1}|\),那么\(s'=s-|a_{l-1}-a_l|-|a_r-a_{r+1}|......
  • AtCoder Regular Contest 117 D Miracle Tree
    洛谷传送门AtCoder传送门第一步就没想到可以考虑化简限制。设所有点按\(E_i\)从小到大排序后顺序是\(p_1,p_2,...,p_n\)。发现只需满足\(E_{p_{i+1}}-E_{p_i}\ge\operatorname{dis}(p_i,p_{i+1})\)。证明是对于任意\(i<j<k\),若\(p_i,p_j\)和\(p_j,p_k\)均满......
  • 剑指 Offer II 119. 最长连续序列
     分析:题目意思是数组里面能组合起来最长的连续数组然后直接sort排序,如果中间差数不是1就不再连续,count归零当nums[i]和nums[i-1]相等的时候,跳过代码:1classSolution(object):2deflongestConsecutive(self,nums):3"""4:typenums:List[......
  • AtCoder Beginner Contest 231
    A-WaterPressure#include<bits/stdc++.h>usingnamespacestd;intmain(){ intn; cin>>n; printf("%.6lf\n",n/100.0);return0;}B-Election#include<bits/stdc++.h>usingnamespacestd;intmain(){ ios:......
  • AtCoder比赛记录(一)
    这里记录的是这个账号的比赛情况。ARC1572023-2-25Solved:4/62189->2216C(Medium,1802)给定一个XY矩阵,一条左上角到右下角的路径的分值定义为路径上连续两个Y的组数。求所有可能路径的分值的平方和。Solution:经典DP。递推两个量,一个是到(i,j)所有路径的分值和\(f_{i,j}\),......