--- 这里是 cjiaw 的小窝(●'◡'●) ---

正在玩命加载中......

CF_2193_F. Pizza Delivery(DP)

题目链接:Problem - 2193F - Codeforces


题目大意:

从起点(Ax, Ay)出发,每次可向右、向左或向下移动一格,需依次经过n个给定点(横坐标严格介于Ax与Bx之间),

最后到达终点(Bx, By)。每移动一格耗时1秒,求最短总时间。


思路:

由于开始写题时理解有些偏差,这里的x轴是纵轴,y是横轴

首先,对于x轴,走的路程是固定的,因为不能往上走

然后,对于y轴,对于相同的x坐标,最后要往下走时只能是位于当前x轴的最左边或最右边,因为不能从左走到右再回到中间的位置往下走,反之亦然

再记录相同x轴上的最左端点的位置与最右端点的位置,

我们用f[x][0]表示位于x轴上最左端时的最短时间,f[x][1]表示位于x轴上最右端时的最短时间

最后求出min(f[lst][0],f[lst][1])就是y轴上一共走过的距离

答案就是y轴上走的距离+x轴上走过的距离(固定=bx-ax)

image

橙色部分为走过的距离


代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<bitset>
#include<tuple>
#include<array>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;

const int N = 200086, mod = 998244353;

int n, ax, ay, bx, by;
pii e[N];
int f[N][2];

void solve() {

    cin >> n >> ax >> ay >> bx >> by;
    vector<array<int, 2>> t(n + 2);
    for (int i = 1; i <= n; i++) cin >> e[i].F;
    for (int i = 1; i <= n; i++) {
        cin >> e[i].S;
        t[i][0] = inf, t[i][1] = -inf;
    }
    
    e[0] = {ax, by};
    e[n + 1] = {bx, by};
    t[n + 1] = {inf, -inf};
    n++;
    sort(e, e + n + 1);
    
    int idx = 0;
    for (int i = 1; i <= n; i++) {
        auto [x, y] = e[i];
        if (e[i - 1].F != x) idx++;
        t[idx][0] = min(t[idx][0], y);
        t[idx][1] = max(t[idx][1], y);
    }
    
    t[0][0] = t[0][1] = ay;
    for (int i = 1; i <= idx; i++) {
        f[i][0] = min(f[i - 1][0] + abs(t[i - 1][0] - t[i][1]) + (t[i][1] - t[i][0]),
                      f[i - 1][1] + abs(t[i - 1][1] - t[i][1]) + (t[i][1] - t[i][0]));                
        f[i][1] = min(f[i - 1][0] + abs(t[i - 1][0] - t[i][0]) + (t[i][1] - t[i][0]),
                      f[i - 1][1] + abs(t[i - 1][1] - t[i][0]) + (t[i][1] - t[i][0]));
    }
    
    cout << min(f[idx][0], f[idx][1]) + bx - ax << endl;
}

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    
    int T = 1;
    cin >> T;
    while (T--) solve();
    
    return 0;
}

 

posted @ 2026-02-07 00:39  wwjjw  阅读(23)  评论(0)    收藏  举报