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();
}
}