“科大讯飞杯”第十七届同济大学程序设计预选赛暨高校网络友谊赛

张老师的旅行

https://ac.nowcoder.com/acm/contest/5477/C

C、张老师的旅行

区间dp,动态规划众多模型中的一种,解决区间问题上有广泛的应用。
基本思想就是一重循环枚举长度,还要一重循环枚举起点,终点就已经确定。
关于决策点根据题目是否需要枚举或者优化成记录这里不展开。本题不需要枚举决策点,因为老师需要花费时间最短一定是从区间这一边一直走到另一边。

那么我们根据题目意思找到n小于等于1000,可以开下2维的数组,我们就通过区间dp去解题。
使用一个三维数组,前两维表示左端点和右端点最后一个表示最后落点,0代表左端点,1代表右端点。它的值记录最短花费时间。
那么我们可以发现状态转移分别是:

  • 从左端点继续向左
  • 从右端点继续向右
  • 从左端点一路向右到右端点后一个位置
  • 从右端点一路向左到左端点前一个位置

当然这些状态转移的前提都是前一个位置的最小耗费,加上你的路途花费小于等于题目给定的t[i]。

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;

inline int read() {
    int s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}

const int N = 1e3 + 7; //节点
int dp[N][N][2];
int a[N], t[N];

int main() {
    int n = read();
    for (int i = 1; i <= n; ++i)    a[i] = read();
    int st = -1;
    for (int i = 1; i <= n; ++i) {
        t[i] = read();
        if (!t[i])    st = i;
    }
    memset(dp, 0x3f, sizeof(dp));
    dp[st][st][0] = dp[st][st][1] = 0;
    for (int len = 1; len <= n; ++len) { //长度
        for (int i = max(1, st - len + 1); i <= st && i + len - 1 <= n; ++i) { //起点
            int j = i + len - 1; //终点
            if (dp[i + 1][j][0] + a[i + 1] - a[i] <= t[i])
                dp[i][j][0] = min(dp[i][j][0], dp[i + 1][j][0] + a[i + 1] - a[i]);
            if (dp[i + 1][j][1] + a[j] - a[i] <= t[i])
                dp[i][j][0] = min(dp[i][j][0], dp[i + 1][j][1] + a[j] - a[i]);
            if (dp[i][j - 1][1] + a[j] - a[j - 1] <= t[j])
                dp[i][j][1] = min(dp[i][j][1], dp[i][j - 1][1] + a[j] - a[j - 1]);
            if (dp[i][j - 1][0] + a[j] - a[i] <= t[j])
                dp[i][j][1] = min(dp[i][j][1], dp[i][j - 1][0] + a[j] - a[i]);
        }
    }
    int ans = min(dp[1][n][0], dp[1][n][1]);
    if (ans == 0x3f3f3f3f)    puts("-1");
    else    printf("%d\n", ans);
    return 0;
}
全部评论

相关推荐

面试摇了我吧:啊哈哈面试提前五个小时发,点击不能参加就是放弃
点赞 评论 收藏
分享
点赞 评论 收藏
分享
评论
点赞
收藏
分享
牛客网
牛客企业服务