C. Robot in a Hallway - Educational Codeforces Round 133

题意

2 * m的网格 从(1,1 )出发每个格子都要走正好一次 每个格子都有时间要求 对于每个格子至少经过a[i][j]的时间 才能走格子(i, j)问走遍格子的最少时间

思路

如果从起点出发 往右走 那只能够走到第一行尾再走第二行这一种走法 而如果我们一开始往下走 那我们可以先走一段蛇形然后再走到底换行(U型)
蛇形过程的最小时间是很容易求得 时间复杂度主要在计算走U型这个过程 我们可以用dp来快速计算
dp[i][j]代表从(i,j)这格开始走U型最少到达该格的时间 最后我们枚举从每个格子走U型的花费时间 取最小值即可

#include<bits/stdc++.h>
#include<iostream>
#include<vector>
#include<array>
#include<unordered_map>
#include<ctime>
#include<random>
#define ll long long
#define ull unsigned long long
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
const ll inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double eps = 1e-10;
const ll N = 2e5 + 5;
const ll M = 1e6;
const ll mod = 998244353;
ll n, m, dp[2][N], a[2][N], tt[2][N];

void solve()
{
	cin >> m;
	for (int i = 0; i < 2; i++) 
		for (int j = 1; j <= m; j++) 
			cin >> a[i][j];
	dp[0][m + 1] = dp[1][m + 1] = 0;
        //U型
	for (int i = 0; i < 2; i++)
		for (int j = m; j >= 2; j--) 
			dp[i][j] = max({ dp[i][j + 1] - 1, a[i][j] + 1, a[i ^ 1][j] - 2 * (m - j) });
        //应该特殊处理第一列的位置 
	dp[0][1] = max(dp[0][2] - 1, a[1][1] - 2 * (m - 1));//到达(1,1)不用等待时间
	dp[1][1] = max(dp[1][2] - 1, a[1][1] + 1);//只能从(1,1)出发

	ll ans = INF;
        //蛇形
	tt[0][1] = 0;
	tt[1][1] = max(1ll, a[1][1] + 1);
	for (int i = 2; i <= m; i++) {
		if (i % 2) {
			tt[0][i] = max(tt[0][i - 1] + 1, a[0][i] + 1);
			tt[1][i] = max(tt[0][i] + 1, a[1][i] + 1);
		}
		else {
			tt[1][i] = max(tt[1][i - 1] + 1, a[1][i] + 1);
			tt[0][i] = max(tt[1][i] + 1, a[0][i] + 1);
		}
	}
        //枚举开始走U型的位置取最小值 不难看出列序号为奇数只能从上一行开始走U型 偶数只能从下一行开始走U型
	for (int j = 1, i; j <= m; j++) {
		if (j % 2) i = 0;
		else i = 1;
		ans = min(ans, max(dp[i][j], tt[i][j]) + (m - j) * 2 + 1);
	}	
	ans = min(ans, !(m % 2) ? tt[0][m] : tt[1][m]);//加上第一列的两种情况
    cout << ans << "\n";
}

signed main() {
	IOS;
	int t = 1;
	cin >> t;
	while (t--) {
		solve();
	}
}
posted @ 2022-08-13 21:58  Yaqu  阅读(87)  评论(6)    收藏  举报