题意:2*m的矩阵中从(1,1)出发,可以进行两种操作:等待或花一秒时间走一格,每个格子有开放时间且只能通过一次,求走完所有格子的最短时间
思路:因为行数很少且只能一笔画,限制较多,所以走一遍发现合法路径是固定的:
①如果→则此时不可以↓(左下的格子走后不合法)只能→直到边界后↓一直←,路线是回字形
②如果↓→,此时若↑→则回到第一种情况,路线是s型或一个凸+回字形;③此时若→则变成第一种情况的镜像回字形
综上所述,固定的路线是:当连续向右走两步则后续路线一定是回字形,就可以开始递推了。设a[i][j]为从第 i 列出发走回字形到第j列花费的时间。注意边界取决于总列数的奇偶性,如果 j 是奇数,那么从第一行出发,否则从第二行出发。但是这个时间并不能保证第 j 列前所有的点已经解锁,所以 cur表示能通过第 j 列前面所有的点最小时间,max(cur, b[i][j])就能保证第 j 列前后的点都能通过
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
//#define int long long;
//#define x first
//#define y second
const int N=2e5+10;
int a[2][N], f[2][N];
//int n, m;
void solve()
{
int n;cin>>n;
for(int i=0;i<2;i++)
for(int j=1;j<=n;j++)
cin>>a[i][j];
a[0][1] = -1;
f[0][n] = max(a[0][n]+2 , a[1][n]+1);
f[1][n] = max(a[1][n]+2 , a[0][n]+1);
for(int i=n-1;i>=1;i--){
f[0][i] = max(f[0][i+1]+1,max(a[1][i]+1, a[0][i]+2*(n-i+1)));
f[1][i] = max(f[1][i+1]+1,max(a[0][i]+1, a[1][i]+2*(n-i+1)));
}
int time = -1;
int ans = f[0][1];
for(int i=1;i<=n;i++){
int cur = (i-1)&1;
time = max(a[cur][i], time)+1;
time = max(time, a[cur^1][i])+1;
if(i==n) break;
ans = min(ans,max(time+2*(n-i), f[cur^1][i+1]));
}
cout<<min(ans, time) << endl;
}
int main(){
int T;cin>>T;
while(T--) solve();
}