当前位置: 首页 > news >正文

4 ACwing 274 Mobile Service 题解

Mobile Service

题面

一个公司有三个移动服务员,最初分别在位置 1,2,3 处。

如果某个位置(用一个整数表示)有一个请求,那么公司必须指派某名员工赶到那个地方去。

某一时刻只有一个员工能移动,且不允许在同样的位置出现两个员工。

从 p 到 q 移动一个员工,需要花费 c(p,q)。

这个函数不一定对称,但保证 c(p,p)=0。

给出 N 个请求,请求发生的位置分别为 p1∼pN。

公司必须按顺序依次满足所有请求,且过程中不能去其他额外的位置,目标是最小化公司花费,请你帮忙计算这个最小花费。

\(3 \le L \le 200\)

\(1 \le N \le 1000\)

题解

因为公司必须按顺序满足所有请求,所以我们可以按照这些请求划分阶段,设 \(f(i,p1,p2,p3)\) 表示处理完前 \(i\) 个请求,三个人分别在 \(p1,p2,p3\) 的最小代价

如果这样 \(dp\) ,那么状态数是 \(O(NL^3)\) 级别的,是不可接受的

仔细观察发现,这三个位置中一定有一个位置在第 \(i\) 个请求的位置,所以我们可以只记两个位置,\(f(i,p1,p2)\) 表示完成前 \(i\) 个请求,有一个人在 \(i\) 请求的位置,另外两个人在 \(p1,p2\) 的最小代价,这样的状态数就是 \(O(NL^2)\) 的,大概 4e7 ,可以接受

转移

\[f(i + 1,x,y) = f(i,x,y) + c(p_i,p_{i + 1}) \\ f(i + 1,x, p_i) = f(i, x, y) + c(y,p{i + 1}) \\ f(i + 1, p_i, y) = f(i, x, y) + c(x, p_{i + 1}) \]

这道题给我们两点启发:

  1. 求解线性dp问题,一般先确定阶段,若阶段不足以表示一个状态,则可以把所需的附加信息也作为状态的维度

    在转移时,若总是从一个阶段转移到下一个阶段(本题 i -> i+1),则没有必要关心附加信息维度的大小变化情况(本题 x,y 在转移前后大小不定),因为无后效性已由阶段保证

  2. 在确定 dp 状态时,要选择最小的能够覆盖整个状态空间的 “维度集合”

    若 dp 状态由多个维度构成,则应检查维度之间能否相互导出,排除冗余维度

code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>using namespace std;const int N = 1010, M = 210;int n, m;
int p[N], c[M][M];
int f[N][M][M];int main () {cin >> m >> n;for (int i = 1; i <= m; i++) {for (int j = 1; j <= m; j++) {cin >> c[i][j];}}for (int i = 1; i <= n; i++) {cin >> p[i];}memset (f, 0x3f, sizeof f);f[0][1][2] = 0;//自己的初始化要符合定义p[0] = 3;for (int i = 0; i <= n; i++) {for (int j = 1; j <= m; j++) {for (int k = 1; k <= m; k++) {int x = p[i];//注意判断不合法状态if (x == j || x == k || j == k) continue;//可以在合适的地方用变量简化代码int v = f[i][j][k];f[i + 1][j][k] = min (f[i + 1][j][k], v + c[x][p[i + 1]]);f[i + 1][j][x] = min (f[i + 1][j][x], v + c[k][p[i + 1]]);f[i + 1][x][k] = min (f[i + 1][x][k], v + c[j][p[i + 1]]);}}}int ans = 2e9;for (int i = 1; i <= m; i++) {for (int j = 1; j <= m; j++) {ans = min (ans, f[n][i][j]);}}cout << ans << endl;return 0;
}
http://www.hskmm.com/?act=detail&tid=25019

相关文章:

  • 3 ACwing 273 Making the Grade 题解
  • 1 ACwing 271 Mr
  • 2 ACwing 272 LCIS 最长公共上升子序列 题解
  • 用 Haxe 实现英文数字验证码识别
  • 出题四
  • 7 2025 07 15 模拟赛题解
  • 使用 OCaml 实现验证码识别
  • 私有云大数据部署:从开发到生产(Docker、K8s、HDFS/Flink on K8s) - 详解
  • 差分约束模板
  • 17 LCA模拟赛1T2 剧院始于演员 题解
  • 3 2025 04 23 模拟赛总结
  • 14 收心赛3 T1 最长不降子序列 题解
  • 16 LCA模拟赛1T1 密码 题解
  • 吴恩达深度学习课程一:神经网络和深度学习 第二周:神经网络基础(一)
  • 阿里开源规则引擎QLExpress
  • QOJ7411 Bitwise Xor
  • 完整教程:SOC-ESP32S3部分:25-HTTP请求
  • 为什么要采用“接口 - 抽象类 - 实现类”这种三层结构? - 浪矢
  • 对外提供 AI 服务的风险:合规视角与 AI 安全围栏落地指南
  • VScode C/C++ 汉化 竞赛版 只需下载扩展 (超简单)
  • 网络安全工具与社区讨论月报
  • 机器人运动未来与人机交互研究
  • 欧拉路径 欧拉图 小记
  • OI 笑传 #16
  • cf296b
  • 第一次使用Ttpora
  • Apache反向代理
  • 原版 Sunshine+虚拟显示器实现熄屏串流
  • 2025国庆Day4
  • gis坐标计算