AcWing 274. 【Java】移动服务
原题链接
中等
作者:
tt2767
,
2020-01-10 01:39:03
,
所有人可见
,
阅读 746
/*
1. 状态定义: 花费最小 -> 什么状态花费最小? -> 服务员在x,y,z 时 f[x][y][z]最小
-> 请求来源是线性的 -> 处理完第i请求时的花费是可以递推的 -> 处理完1..i 个请求时 f[i][x][y][z] 最小
-> 处理第i个时必定有一个员工在i处 -> 即求处理完1..i 个请求时的代价f[i][a][b]
2. 状态计算:
2.1 状态转移:“把每个状态看成一张表,DP就是求最短路”,根据每次指派到第i+1个点的情况向后递推
f[i][a][b] = MIN(f[i][a][b] , f[i-1][a][b] + cost(p[i-1], p[i]))
2.2 合法性计算: if (x == y || x == z || y == z) continue;
2.3 边界条件: 假定0号任务由任意p[0] 去,故设f[0][2][3] = 0, p[0] = 1
取MIN所以初始化为INF
需要设定0, 所以哨兵也要初始化为INF
*/
import java.util.*;
public class Main{
void run(){
int l = jin.nextInt();
int n = jin.nextInt();
for (int i = 1 ; i <= l; i++)
for (int j = 1; j <= l; j++)
cost[i][j] = jin.nextInt();
for (int i = 1 ; i <= n ; i++) p[i] = jin.nextInt();
for (int i = 0 ; i <= n ; i++){ // 初始化从0 开始
for (int x = 0; x <= l ; x++){
for (int y = 0 ; y <= l ; y++){
f[i][x][y] = Integer.MAX_VALUE >> 1;
}
}
}
f[0][2][3] = 0;
p[0] = 1;
// for (int i = 1 ; i <= n ; i++){
for (int i = 0 ; i < n ; i++){
for (int x = 1; x <= l ; x++){
for (int y = 1 ; y <= l ; y++){
int z = p[i];
if (x == y || x == z || y == z) continue;
int v = f[i][x][y];
int next = p[i+1];
f[i+1][x][y] = Math.min(f[i+1][x][y], v + cost[z][next]);
f[i+1][x][z] = Math.min(f[i+1][x][z], v + cost[y][next]);
f[i+1][y][z] = Math.min(f[i+1][y][z], v + cost[x][next]);
}
}
}
int res = Integer.MAX_VALUE;
for (int x = 1 ; x <= l ; x++){
for (int y = 1; y <= l; y++){
int z = p[n];
if (x == y || x == z || y == z) continue;
res = Math.min(res, f[n][x][y]);
}
}
System.out.println(res);
}
int maxN = 1002;
int maxL = 202;
int[] p = new int[maxN];
int[][][] f = new int[maxN][maxL][maxL];
int[][] cost = new int[maxL][maxL];
Scanner jin = new Scanner(System.in);
public static void main(String[] args) {new Main().run();}
}
大佬,很厉害了。上次杨老师照相排列,因为要重置5维数组,一直没有解决,最后看到你的分享,才ac。厉害了
%% JavaDalao
并不是dalao,都是看了视频敲的,不过是看大家之前都是用c艹,退役狗来发一份Java的😂