(规律,DP)Educational Codeforces Round 133 C

题意: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();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值