ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF EDU 133 C - Robot in a Hallway

2022-08-13 16:03:12  阅读:169  来源: 互联网

标签:Hallway idx int Robot else 133 ans id op


st表 or 后缀和 优化dp

C - Robot in a Hallway

题意

有一个两行 n 列的网格,每个格子有一个解锁时间 \(a[i][j]\) (注意这个是解锁的时间,最早到达该点的时间要 + 1), 过了这个时间才能走进这个格子。每秒可以选择上下左右移一格或者不动,求从 (0, 0) 出发恰好每个格子走一次的最短时间

思路

只有三种可能

1660376122867

1660376292251

  1. 1660376580246

可预处理出走蛇形走到 (i, j) 的时间 \(h[i][j]\)

走蓝线的时间为 走蓝线区间不停顿的时间 - 在某个格子等待的最长时间

以图 3 为例,可以给格子按

1660376506426

标号 id

设走到 \((i-1,j)\) 后之后都按 3 的蓝线走,则蓝线时间为

\(id[i][0]-id[i-1][1]+max(0,a[k][j]-(h[i-1][1]+id[k][j]-id[i-1][1]))\)

所以用 st 表维护 \(a[k][j]-id[k][j]\) 的最大值即可 (也可预处理出上下两行的后缀和,复杂度会少一个log)

#include <bits/stdc++.h>
using namespace std;
#define endl "\n"

typedef long long ll;
typedef pair<int, int> PII;

const int N = 4e5 + 10, M = 20;

int h[N][2], a[N][2];
int id[N][2];
int n;
void presolve()
{
	h[0][0] = 0;
	for (int k = 1; k < 2 * n; k++)
	{
		int i = k / 2;
		if (k % 4 == 0)
			h[i][0] = max(h[i-1][0] + 1, a[i][0]);
		else if (k % 4 == 1)
			h[i][1] = max(h[i][0] + 1, a[i][1]);
		else if (k % 4 == 2)
			h[i][1] = max(h[i-1][1] + 1, a[i][1]);
		else
			h[i][0] = max(h[i][1] + 1, a[i][0]);
	}
}
int hs(int idx, int op)
{
	int i, j;
	if (op == 0)
	{
		j = idx / n;
		if (j == 0)
			i = idx;
		else
			i = 2 * n - 1 - idx;
	}
	else
	{
		j = (idx / n) ^ 1;
		if (j == 1)
			i = idx;
		else
			i = 2 * n - 1 - idx;
	}
	return a[i][j] - id[i][j];
}

template<typename T> struct ST
{
    ST(int n, int op)
    {
        siz = n;
        maxv.resize(n+1);
        int t = __lg(n) + 1;
        for(int i=0;i<n;i++) maxv[i].resize(t);
        
        for(int i = 0; i < n; i++) maxv[i][0] = hs(i, op);
        for(int j = 1; j < t; j++) 
            for(int i = 0; i < n - (1<<j)+1; i++)
                maxv[i][j] = max(maxv[i][j-1], maxv[i+(1 << (j-1))][j-1]);
    }
    T getmax(int l,int r)
	{
	    int k = __lg(r-l+1);
	    return max(maxv[l][k],maxv[r-(1<<k)+1][k]);
    }      
private:
    int siz = 0;
    vector<vector<T>> maxv;
};

int solve(int op)
{
	for (int i = 0; i < n; i++)
	{
		id[i][op] = i;
		id[i][op^1] = 2 * n - 1 - i;
	}
	ST<int> s(2*n, op);
	int ans;
	if (op == 0)
		ans = 2 * n - 1 + max(0, s.getmax(1, 2 * n - 1));
	else
		ans = 2e9;
	int first = op ? 1 : 2;
	for (int i = first; i < n; i += 2)
	{
		int l = i, r = 2 * n - i - 1;
		int now = h[i-1][op] + id[i][op^1] - id[i-1][op] + max(0, s.getmax(l, r) + id[i-1][op] - h[i-1][op]);
		ans = min(ans, now);
	}
	return ans;
}
int main()
{
	ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	int T;
	cin >> T;
	while(T--)
	{
		cin >> n;
		for (int j = 0; j < 2; j++)
		{
			for (int i = 0; i < n; i++)
			{
				int x;
				cin >> x;
				a[i][j] = x + 1;
			}
		}
		a[0][0] = 0;
		presolve();
		int ans = min(solve(0), solve(1));
		cout << ans << endl;
	}
    return 0;
}

标签:Hallway,idx,int,Robot,else,133,ans,id,op
来源: https://www.cnblogs.com/hzy717zsy/p/16583209.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有